Cloneable接口、深复制和浅复制
Cloneable
接口
- 在看
ArrayList
源码时遇到这个接口,所以研究了一下
public interface Cloneable
- 一个类实现
Cloneable
接口,以指示Object.clone()
方法,该方法对于该类的实例进行现场复制是合法的。 - 在不实现
Cloneable
接口的实例上调用对象的克隆方法导致抛出异常CloneNotSupportedException
- 按照惯例,实现此接口的类应使用公共方法覆盖
Object.clone()
。有关覆盖此方法的详细信息,请参阅Object.clone()
。
- 一个类实现
protected Object clone() throws CloneNotSupportedException
- 创建并返回此对象的副本。“复制”的精确含义可能取决于对象的类。一般的意图是对于任何对象而言
x.clone()!=x
为truex.clone().getClass()==x.getClass()
为true- 这些不是绝对要求
x.clone().equal(x)
为true- 以上也不是绝对要求
- 个人觉得以上对比只是定义层面的解释,但没有实际意义,因为默认(即不重写
equal()
)情况下,等号运算符equal()
方法的行为是一致的
- 创建并返回此对象的副本。“复制”的精确含义可能取决于对象的类。一般的意图是对于任何对象而言
示例
package pojo;
/**
* @author ssk
* @date 2020/5/19 18:46
* @desc
*/
public class Person implements Cloneable{
private String name;
private String job;
public Person(String name, String job) {
this.name = name;
this.job = job;
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
}
@Test
public void testCloneable() throws CloneNotSupportedException {
Person person = new Person("卡卡西", "木叶上忍");
Object clone = person.clone();
Person person2 = (Person) clone;
person2.setJob("六代火影");
System.out.println("x.clone().getClass() == x.getClass():"+(clone.getClass()==person.getClass()));
System.out.println("x.clone() != x:" + (clone != person));
System.out.println("x.clone().equals(x):" + (person2.equals(person)));
}
- 运行结果:
x.clone().getClass() == x.getClass():true
x.clone() != x:true
x.clone().equals(x):false
深复制和浅复制
以下内容参考自 Cloneable接口和Object的clone()方法
- 深复制和浅复制描述的是,当对象中还组合有其它对象时
- 浅复制时:如果我们要复制对象,只复制它自身以及它所包含的所有对象的引用地址
- 深复制时:将其它对象的引用复制值新对象
- 对于基本数据类型,无论深复制还是浅复制,都会进行原值拷贝
publice class Person{
private Address address;
}
- 即对于
Person
来说- 如果是深复制:
person.getAddress()!=person.clone().getAddress()
- 如果是浅复制:
person.getAddress()==person.clone().getAddress()
- 如果是深复制: