java使用赋值符号(=)给对象赋值时(A a=b;),并不是将b对象的值给赋值给a,而是a对象指向b对象的引用地址,两者同时引用一个地址,所以任何一个对象属性值的改变将会引起另一个对象属性值的改变,基本类型使用赋值是值拷贝。
public class test {
public static void main(String[] args) throws CloneNotSupportedException {
Admin admin=new Admin();
Admin admin1=admin;
System.out.println(admin1);
System.out.println(admin);
}
}
com.example.domain.Admin@816f27d
com.example.domain.Admin@816f27d
要实现对象的拷贝可以使用Object类中的clone方法,拷贝分为深拷贝和浅拷贝。
浅拷贝
结论:基本类型值拷贝,子对象共享。
实现方法
1、实现接口Cloneable(该接口为标记接口无实现方法,用于标记开发者了解拷贝过程,不写会抛出CloneNotSupportedException 异常)
2、重写Object类的clone方法,并将protected权限改为public
如果共享子对象是不可变的(如String)浅拷贝是安全的。
public class Admin extends Entity implements Cloneable{
//子对象
private AnswerOption answerOption;
/*浅拷贝*/
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class test {
public static void main(String[] args) throws CloneNotSupportedException {
Admin admin=new Admin();
AnswerOption answerOption=new AnswerOption();
admin.setAnswerOption(answerOption);
Admin admin1= (Admin) admin.clone();
//对象引用地址
System.out.println(admin1);
System.out.println(admin);
//子对象引用地址
System.out.println(admin1.getAnswerOption());
System.out.println(admin.getAnswerOption());
}
}
print:
com.example.domain.Admin@816f27d
com.example.domain.Admin@87aac27
com.example.domain.AnswerOption@3e3abc88
com.example.domain.AnswerOption@3e3abc88
结论:基本类型值拷贝,子对象共享。
深拷贝
结论:通通拷贝
实现方法
1、实现接口Cloneable(该接口为标记接口无实现方法,用于标记开发者了解拷贝过程,不写会抛出CloneNotSupportedException 异常)
2、重写Object类的clone方法,自定义规则,并将protected权限改为public
public class Admin extends Entity implements Cloneable{
//子对象
private AnswerOption answerOption;
//深拷贝
@Override
public Admin clone() throws CloneNotSupportedException{
Admin admin= (Admin) super.clone();
//通过子对象的拷贝子对象(数组自带public的clone)
admin.answerOption= (AnswerOption) answerOption.clone();
return admin;
}
}
public class test {
public static void main(String[] args) throws CloneNotSupportedException {
Admin admin=new Admin();
AnswerOption answerOption=new AnswerOption();
admin.setAnswerOption(answerOption);
Admin admin1= (Admin) admin.clone();
//对象引用地址
System.out.println(admin1);
System.out.println(admin);
//子对象引用地址
System.out.println(admin1.getAnswerOption());
System.out.println(admin.getAnswerOption());
}
}
print:
com.example.domain.Admin@816f27d
com.example.domain.Admin@87aac27
com.example.domain.AnswerOption@3e3abc88
com.example.domain.AnswerOption@6ce253f1
结论:通通拷贝的干活