如图所示
浅拷贝、深拷贝原型模式
深拷贝和浅拷贝的区别(copy的是值还是引用)
1.浅拷贝: 将原对象或原数组的引用直接赋给新对象,新数组,新对象/数组只是原对象的一个引用
2.深拷贝: 创建一个新的对象和数组,将原对象的各项属性的“值”(数组的所有元素)拷贝过来,是“值”而不是“引用”
java的传递类型:java传递的话只有值传递,不存在引用传递。
浅拷贝(Shallow Copy):基本数据类型和引用数据类型。
①对于数据类型是基本数据类型的成员变量,浅拷贝会直接进行值传递,也就是将该属性值复制一份给新的对象。因为是两份不同的数据,所以对其中一个对象的该成员变量值进行修改,不会影响另一个对象拷贝得到的数据。
②对于数据类型是引用数据类型的成员变量,比如说成员变量是某个数组、某个类的对象等,那么浅拷贝会进行引用传递,也就是只是将该成员变量的引用值(内存地址)复制一份给新的对象。因为实际上两个对象的该成员变量都指向同一个实例。在这种情况下,在一个对象中修改该成员变量会影响到另一个对象的该成员变量值。
浅拷贝:值类型直接copy一份,修改原有的值对现在的值无影响。
使用原型模式实现的是深拷贝;步骤:1)实现Cloneable接口;2)在clone()方法里面处理copy逻辑。
String是引用数据类型,但是字符串是不可变类型,所以当做值类型来处理。
基本数据类型浅拷贝与深拷贝等同,引用类型是多个对象公用一块内存,当一个对象去改变值时,其他也会受影响。
对于引用类型的修改,不能影响到对应的copy对象的值。
浅拷贝与深拷贝的区别。
为什么要使用深拷贝?我们希望在改变新的数组或者对象的时候,不改变原数组或对象
引用类型,所以它们是指向同一个内存地址。
Java 中的数据类型分为基本数据类型和引用数据类型。对于这两种数据类型,在进行赋值操作、用作方法参数或返回值时,会有值传递和引用(地址)传递的差别。
根据对对象属性的拷贝程度(基本数据类和引用类型),会分为两种:
浅拷贝 (Shallow Copy); 深拷贝 (Deep Copy)
如何实现浅copy?
实现对象拷贝的类,需要实现 Cloneable 接口,并覆写 clone() 方法。
implements Cloneable接口,重写clone()方法,
//直接调用父类的clone()方法 return super.clone();
给Sting类型的变量赋值,就相当于指向了一个新的内存地址,切记。Sting name。
对象拷贝后没有生成新的对象,二者的对象地址是一样的;而浅拷贝的对象地址是不一样的。
浅拷贝会带来数据安全方面的隐患,把原来的值修改掉。
深拷贝,在拷贝引用类型成员变量时,为引用类型的数据成员另辟了一个独立的内存空间,实现真正内容上的拷贝。
深拷贝后,不管是基础数据类型还是引用类型的成员变量,修改其值都不会相互造成影响。
demo地址:Java 浅拷贝和深拷贝 - 简书
使用自带的clone方法,需要实现cloneable接口,不然会
Exception in thread "main" java.lang.CloneNotSupportedException
相对于浅拷贝而言,对于引用类型的修改,并不会影响到对应的copy对象的值。每一层的每个对象都进行浅拷贝=深拷贝。
//修改对应的引用对象的值。(修改引用对象的值)
把String当做基本类型来处理。
//浅拷贝
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
//深拷贝
@Override
protected Object clone() throws CloneNotSupportedException {
StudentCopy1 studentCopy1 = (StudentCopy1) super.clone();
SubjectCopy1 subject = studentCopy1.getSubject();
studentCopy1.setSubject((SubjectCopy1) subject.clone());
return studentCopy1;
}
//深拷贝,更方便,三者选其一即可
@Override
protected Object clone() throws CloneNotSupportedException {
StudentCopy1 studentCopy1 = new StudentCopy1();
studentCopy1.setAge(age);
studentCopy1.setName(name);
studentCopy1.setSubject(subject);
return studentCopy1;
}
深拷贝方法具有局限性,还不如自己创建对象,实现深拷贝。
1、如果多层级需要深拷贝,需要一层层拷贝下去;
2、里面的类型可能没有实现Cloneable接口;