java的引用拷贝和对象拷贝【浅拷贝和深拷贝】

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。另外这是本人纯手写理解的,喜欢的点个赞呗,多谢

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值