1.什么是引用拷贝?使用引用拷贝会出现什么问题?
在java中我们常常会用到拷贝,如以下的形式
引用拷贝:
Person person = new Person();
Person copyPerson = person;
这就是引用拷贝,引用拷贝他并没有重新建立一个对象,而是新对象和旧对象同时指向同一个地址。
这就会出现当修改了person旧对象里的属性值,copyPerson的属性值同样会被修改。
所以我们还是要注意下使用引用拷贝
2.什么是对象拷贝?
对象拷贝分为浅拷贝和深拷贝
2.1浅拷贝
话不多说,上例子
新建一个Person类,Address类
@Data
public class Person implements Cloneable {
private String name;
private Integer age;
private Address address;
public Person(String name, Integer age, Address address) {
this.name = name;
this.age = age;
this.address = address;
}
//重写Object类的clone方法
public Object clone() {
Object obj = null;
//调用Object类的clone方法,返回一个Object实例
try {
obj = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return obj;
}
}
@Data
public class Address{
private String email;
private String address;
public Address(String email, String address) {
this.email = email;
this.address = address;
}
}
分析讲解浅拷贝及其测试:
public class JavaCopy {
/**
浅拷贝测试
**/
@Test
public void testShallowCopy() {
1.真正的拷贝成功是什么?
Person originalPerson = new Person("张三", 23, new Address("1663783362@qq.com", "江西省吉安市"));
Person copyPerson = (Person) originalPerson.clone();
原对象originalPerson,我们拷贝了一个对象copyPerson,当我们修改了originalPerson对象中的某个属性(age属性),
copyPerson对象的中的某个属性(age属性)不会受其影响,也就是值不变,这就算是拷贝成功。但是如果修改了
originalPerson对象中的某个属性(address属性),copyPerson对象的中的某个属性(address属性)会受其影响,也就是
值同样被改变,那我们就可以理解为拷贝失败。
2.什么是浅拷贝
在java中分别有基本数据类型和引用类型两种数据类型,浅拷贝指的就是在进行拷贝的时候只是把对象的基本数据类
型给成功拷贝过来了(但是有个特殊的引用类型string,由于它是值是不可变的,所以我们可以理解它也是值不变的基本
数据类型)。但是引用类型(对象,数值,集合等等)虽然也是隐性的拷贝过来,但是拷贝结果可是上面1所说的拷贝
失败这种情况。
3.浅拷贝的实现方式
此例子使用了实现Cloneable接口,再重写clone方法
4.浅拷贝会有什么缺陷以及解决方法
浅拷贝只能将基本数据类型的值拷贝成功,但是将引用类型的值拷贝失败。此时我们可以使用深拷贝来解决这个缺陷
Person originalPerson = new Person("张三", 23, new Address("1663783362@qq.com", "江西省吉安市"));
Person copyPerson = (Person) originalPerson.clone(); //浅拷贝
copyPerson.getAddress().setEmail("null@qq.com"); //修改copyPerson对象的address值
System.out.println("originalPerson:" + originalPerson); //originalPerson的对象address改变
System.out.println("copyPerson:" + copyPerson ); //copyPerson的对象address也同样改变
}
}
2.2深拷贝
理解了浅拷贝,那么深拷贝就更容易理解了,我这里再总结下深拷贝
也直接上例子
@Data
public class Person implements Serializable {
private String name;
private Integer age;
private Address address;
public Person(String name, Integer age, Address address) {
this.name = name;
this.age = age;
this.address = address;
}
}
@Data
public class Address implements Serializable {
private String email;
private String address;
public Address(String email, String address) {
this.email = email;
this.address = address;
}
}
public class JavaCopy {
1.什么是深拷贝
浅拷贝只能将基本数据类型的值拷贝成功,但是将引用类型的值拷贝失败。此时我们可以使用深拷贝
来解决这个缺陷。也就是说深拷贝我们不仅仅要把对象的基本数据属性拷贝成功,也同样要把对象的
嵌套对象,数组,集合等等这系列的引用类型数据类型拷贝成功,这就是深拷贝
2.深拷贝的实现方式
如下,深拷贝,
1.首先需要给操作深拷贝的类实现Serializable 接口
2.然后调用该序列化的方法进行深拷贝简单且方便
/**
* 深度拷贝
*/
@Test
public void testDeepCopy() {
Person originalPerson = new Person(“张三”, 23, new Address(“1663783362@qq.com”, “江西省吉安市”));
Person copyPerson = CloneUtils.clone(originalPerson); //深度拷贝
copyPerson.getAddress().setEmail("kk@qq.com"); //修改copyPerson的对象address值
System.out.println("originalPerson:" + originalPerson); //originalPerson的对象address值未受到影响,也就是值没变
System.out.println("copyPerson:" + copyPerson); //copyPerson的对象address的值正常被修改
}
}
public class CloneUtils {
/**
* 深度序列化拷贝
* 拷贝文件的形式来实现深度拷贝
*
* @param object
* @param <T>
* @return
*/
@SuppressWarnings("unchecked")
public static <T extends Serializable> T clone(T object) {
T cloneObj = null;
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream obs = new ObjectOutputStream(out);
obs.writeObject(object);
obs.close();
ByteArrayInputStream ios = new ByteArrayInputStream(out.toByteArray());
ObjectInputStream ois = new ObjectInputStream(ios);
cloneObj = (T) ois.readObject();
} catch (Exception e) {
e.printStackTrace();
}
return cloneObj;
}
}
以上的整理希望能帮助大家更好的理解该方便的知识,当然有什么问题或者新技术方面的探讨也可以在
下方留言评论哈,我会及时回复的呢。或者可以加本人扣扣1663783362@qq.com。另外这是本人纯手写理解的,喜欢的点个赞呗,多谢