直接上代码
public class User implements Cloneable{
private int age;
private String name;
public User(int age, String name) {
this.age = age;
this.name = name;
}
@Override
protected User clone() throws CloneNotSupportedException {
User user = null;
user = (User) super.clone();
return user;
}
//这里省略的了get/set/toString方法。
}
public class CloneTest {
public static void main(String[] args) throws CloneNotSupportedException {
User user = new User(20, "张三", new ClassInfo("教一"));
User clone = user.clone();
System.out.println(user.hashCode() + "----" + clone.hashCode());
System.out.println(user.getClassInfo().hashCode() + "----" + clone.getClassInfo().hashCode());
clone.setAge(21);
clone.setName("李四");
clone.getClassInfo().setClassName("教二");
System.out.println("原对象:" + user);
System.out.println("克隆对象:" + clone);
}
}
//输出:
2016447921----666988784
1414644648----1414644648
原对象:User{age=20, name='张三', classInfo=ClassInfo{className='教二'}}
克隆对象:User{age=21, name='李四', classInfo=ClassInfo{className='教二'}}
实现Clone:
- 需要实现Cloneable接口,不实现编译通过,执行会报CloneNotSupportedException异常。
- 实现Cloneable的类应该重写clone()。
克隆后,原对象和克隆对象不是同一个对象,两者hashCode不同;
原对象的对象属性未实现cloneable接口,调用clone后,hashCode相同,且在修改克隆对象的引用属性后,原对象的引用属性也相应修改,说明只克隆了对象的引用,两个引用对象是同一个。
以上则为浅拷贝:指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象。
深拷贝:不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象。
修改代码为:
属性中的对象也实现cloneable接口,并实现clone方法,主类也相应修改clone方法。
//最后输出结果
2016447921----666988784
1414644648----640070680
原对象:User{age=20, name='张三', classInfo=ClassInfo{className='教一'}}
克隆对象:User{age=21, name='李四', classInfo=ClassInfo{className='教二'}}