JDK 版本:1.8
代码地址
1.前言
clone方法能方便的获得一个对象的拷贝,但其中也有些细节需要注意。
2.实现注意事项
2.1 要调用 clone 方法必须实现 Cloneable 接口
如果类没有实现 Cloneable 接口,类的实例却调用了 clone 方法,则会抛出CloneNotSupportedException异常。
用反射机制去调用 Objec 类的 clone 方法,可以观察到这个现象:
Object object = new Object();
Method method = object.getClass().getDeclaredMethod("clone");
method.setAccessible(true);
method.invoke(object);
运行结果:
Caused by: java.lang.CloneNotSupportedException: java.lang.Object
at java.lang.Object.clone(Native Method)
2.2 clone 方法的默认实现是浅拷贝
clone 方法的默认实现是拷贝,即对于类中可变对象没有进行真正的拷贝,只是将该可变对象赋值给了克隆对象对应的字段。修改当前对象中可变对象也会影响到克隆对象中相应的字段。
举个例子来说明下:
private static void shallowCopyTest() {
Person ming = new Person("ming", new String[]{"mingMing", "daMing"});
compareCloneObject(ming);
}
private static void compareCloneObject(Person person) {
try {
Person fakePerson = (Person) person.clone();
System.out.println("person.getNickName() == fakePerson.getNickName() : "
+ (person.getNickName() == fakePerson.getNickName()));
fakePerson.setNickName(0, "compare");
System.out.println(person);
System.out.println(fakePerson);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
private static class Person implements Cloneable {
private String name;
private String[] nickName;
public Person(String name, String[] nickName) {
this.name = name;
this.nickName = nickName;
}
public void setNickName(int index, String nickName) {
this.nickName[index] = nickName;
}
public void setNickName(String[] nickName) {
this.nickName = nickName;
}
public String[] getNickName() {
return nickName;
}
@Over