Java --- 深度拷贝

    拷贝,通俗点讲就是复制。wins 中使用快捷键 ctrl+c 就能完成。但是在 Java 开发中,并不这么简单。当接口请求的参数传递进来后,规范的开发习惯要求程序员复制一份参数实体进行处理,也就是常用的DTO。直接声明自定义实体,然后使用 = 号进行赋值,只是传递了一个引用给自定义实体,并不能自由处理。那么,深度拷贝,就出现了!

    下面,就跟着小编来看下如何进行对象的深度拷贝吧!

一,浅拷贝

public class Test {

    @org.junit.Test
    public void test1(){
        Apple apple = new Apple("ppkk",8);
        //1,传递apple引用给apple1
        Apple apple1 = apple;
        
        System.out.println("apple:" + apple);
        System.out.println("apple1:" + apple1);

        //2,修改apple1属性值,其实修改的是引用的属性值,apple会受影响
        apple1.setPrice(10);
        System.out.println("apple:" + apple);
        System.out.println("apple1:" + apple1);
    }
}
@Data
@AllArgsConstructor
@ToString
public class Apple {

    private String name;
    private int price;
}

输出:

D:\jdk\jdk1.8.0_171\bin\java.exe
apple:Apple(name=ppkk, price=8)
apple1:Apple(name=ppkk, price=8)
apple:Apple(name=ppkk, price=10)
apple1:Apple(name=ppkk, price=10)

二,深度拷贝

1,编写拷贝工具类

public class ObjectCloneUtils {
    
    public static <T> T clone (T src){
        T result = null;
        try (
//                1,开启io字节输出流
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
//                2,装配对象输出流程
                ObjectOutputStream oos = new ObjectOutputStream(baos);
                ){
//            3,把src原对象写入输出流中
            oos.writeObject(src);
//            4,刷新输出流
            oos.flush();
            try (
//                    5,开启io字节输入流
                    ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
//                    6,装配对象输入流
                    ObjectInputStream ois = new ObjectInputStream(bais);
                    ){
//                7,读取输入流中对象数据
                result = (T)ois.readObject();
            }
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
        return result;
    }
}

2,实体对象实现序列化接口,并重写 equals() 方法

public class Apple implements Serializable {
    static final long serialVersionUID = 1L;

    private String name;
    private int price;
    public Apple(String name, int price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

	//重写 equals() 方法
    @Override
    public boolean equals(Object obj) {
        if (this == obj){
            return true;
        }
        if (obj instanceof Apple){
            Apple apple = (Apple) obj;
            return this.name.equals(apple.getName()) && this.price == apple.getPrice();
        }
        return false;
    }
}

3,调用

public class Test {
    @org.junit.Test
    public void test2(){
        Apple apple = new Apple("ppkk",8);

        Apple appleClone = ObjectCloneUtils.clone(apple);

        System.out.println(apple.equals(appleClone));
    }
}

4,输出:

D:\jdk\jdk1.8.0_171\bin\java.exe
true
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

皮皮克克

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值