一、浅复制与深复制概念
(1)浅复制
浅复制会复制“被复制对象”基本类型的值和对象的引用。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。
(2)深复制
深复制会复制“被复制对象”基本类型的值,对象的引用将重新指向一个被复制过的新对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。
二、clone()、Cloneable和Serialiable
(1)clone()与Cloneable
clone()是定义在Object类下的一个方法,定义如下
protected native Object clone() throws CloneNotSupportedException;
官方的注释是创建并返回此对象的副本,与Cloneable接口联合使用。如果未实现Cloneable使用clone()会抛出java.lang.CloneNotSupportedException异常。clone()方法是将对象的属性值通过复制引用的方式完成对象的复制,是浅复制。
public class User implements Cloneable, Serializable {
private int id;
private String name;
public User(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public static void main(String[] args) throws CloneNotSupportedException {
User user = new User(1, "小明");
User cloneUser = (User) user.clone();
System.out.println(user == cloneUser);
System.out.println(user.getId() == cloneUser.getId());
System.out.println(user.getName() == cloneUser.getName());
System.out.println(user.getName().equals(cloneUser.getName()));
}
}
运行结果:
false
true
true
true
(2)Serialiable
Serializable接口是启用其序列化功能的接口。实现java.io.Serializable 接口的类是可序列化的。没有实现此接口的类将不能使它们的任意状态被序列化或逆序列化。通过对象流读写来完成深复制。
public class User implements Cloneable, Serializable {
private int id;
private String name;
public User(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
User user = new User(1, "小明");
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
objectOutputStream.writeObject(user);
ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
User cloneUser = (User) objectInputStream.readObject();
outputStream.close();
objectOutputStream.close();
inputStream.close();
objectInputStream.close();
System.out.println(user == cloneUser);
System.out.println(user.getId() == cloneUser.getId());
System.out.println(user.getName() == cloneUser.getName());
System.out.println(user.getName().equals(cloneUser.getName()));
}
}
运行结果:
false
true
false
true