深入浅出了解面向对象的深克隆和浅克隆
阅读本文需要一定的面向对象基础和JavaIO流的相应知识!
深克隆(要实现深克隆被克隆类以及被克隆类的引用必须实现Serializable接口)
(未实现接口会抛出NotSerializableException异常) 定义:被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。深克隆的是实现实际上是对对象的序列化和反序列化
浅克隆(要实现浅克隆被克隆的类必须实现Cloneable接口)
(未实现接口会跑出CloneNotSupportedException异常) 定义:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。 详细讲解代及实现码如下
实现类:
package com.xiaoqiang;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
/**
* 本案例配合上文解说
* 详细讲解java深克隆浅克隆的区别
* @author xiaoqiang
* @Time 2017年5月5日
*/
public class Student implements Cloneable,Serializable{
private String name;
private int age;
private Date birthday;
public Student(){
super();
}
public Student(String name,
int age, Date birthday) {
super();
this.name = name;
this.age = age;
this.birthday = birthday;
}
public String
getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(
int age) {
this.age = age;
}
public Date
getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Override
public String
toString() {
return "Student [name=" + name +
", age=" + age +
", birthday="
+ birthday +
"]";
}
/**
* 完成浅克隆类需实现Cloneable接口
* @param student
* @return Object
*/
public Object
shallowClone(Student student){
try {
return student.clone();
}
catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return null;
}
/**
* 完成深克隆被克隆的类和类的引用类
* 均实现Serializable接口
* @param student
* @return Object
*/
public Object
deepClone(Student student){
ByteArrayOutputStream bos =
new ByteArrayOutputStream();
ObjectOutputStream oos =
null;
ObjectInputStream ois =
null;
try {
oos=
new ObjectOutputStream(bos);
oos.writeObject(student);
ois =
new ObjectInputStream(
new ByteArrayInputStream(bos.toByteArray()));
return ois.readObject();
}
catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
return null;
}
finally{
try {
bos.close();
oos.close();
ois.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Student student =
new Student(
"小强",
21,
new Date(
"1997",
"06",
"13"));
System.out.println(
"原student类 "+student);
Student shallowCloneStudent = (Student) student.shallowClone(student);
System.out.println(
"浅克隆出来的student "+shallowCloneStudent);
System.out.println(
"浅克隆和深克隆对象对比 "+shallowCloneStudent.equals(student));
System.out.println(
"浅克隆Date和深克隆Date类引用是否相同 "+shallowCloneStudent.getBirthday().equals(student.getBirthday()));
Student deepCloneStudent = (Student) student.deepClone(student);
System.out.println(
"深克隆出来的student "+deepCloneStudent);
System.out.println(
"深克隆和深克隆对象对比 "+deepCloneStudent.equals(student));
System.out.println(
"深克隆Date和深克隆Date类引用是否相同 "+deepCloneStudent.getBirthday().equals(student.getBirthday()));
}
}
引用类
package com.xiaoqiang;
import java.io.Serializable;
/**
* @author xiaoqiang
* @Time 2017年5月5日
*/
public class Date implements Serializable{
private String year;
private String month;
private String day;
public Date(){}
public Date(String year, String month, String date) {
super();
this.year = year;
this.month = month;
this.day = date;
}
public String
getYear() {
return year;
}
public void setYear(String year) {
this.year = year;
}
public String
getMonth() {
return month;
}
public void setMonth(String month) {
this.month = month;
}
public String
getDate() {
return day;
}
public void setDate(String date) {
this.day = date;
}
@Override
public String
toString() {
return year+
"年"+month+
"月"+day+
"日";
}
}