对象的拷贝

前言:

java语言拷贝对象分别为"对象拷贝"、"浅拷贝"、"深拷贝"
不同的拷贝,在互相传值时,有不同的影响

对象拷贝:

java中最常见的对象拷贝,既为对象A=对象B(也称为内存完全拷贝),对象拷贝后不会生成新的对象,二者的内存地址是一样的,也就是说如果把对象B拷贝到对象A,那么改变了对象A里的参数值,对象B的参数值也会跟着变,因为它们引用的是同一个内存地址,所以里面保存的值也是一模一样的,你改了这个,那个也会跟着改变

java中引用数据类型都为对象,但如果是自定义对象,那么自定义对象里有基本数据类型,则拷贝后基本数据类型也会随着修改发生改变

浅拷贝:

浅拷贝和对象拷贝有两个区别,其它全都一样,分别为:

1.内存地址不一样,浅拷贝时会新创建一个内存地址 

2.对象A浅拷贝了对象B,如果对象B里有基本数据类型,那么对象A修改基本数据类型后,并不会影响到对象B,只有在对象A修改引用数据类型时,才会影响到对象B(如果属性是基本类型,拷贝的就是值传递,如果属性是内存地址(引用传递),拷贝的就是内存地址) 

深拷贝:

优点:

深拷贝和前两个相反,也是真正意义上的拷贝,完全独立开辟内存,所以拷贝后修改值不会影响到原对象

缺点:

深拷贝相比前两个速度较慢并且花销较大

对象拷贝的实现:

两个相同对象,直接对象A=对象B,是java中默认的拷贝

浅拷贝的实现:

被拷贝对象需要实现implements Cloneable接口,按CTRL+O弹出可重写方法,输入clone回车,默认会调用return super.clone();(不需要修改)

拷贝时对象A=(对象A)对象B.clone();  因为需要进行强制转换,因此要处理异常,可到重写方法的clone里去捕获异常(默认是抛出)

深拷贝的实现:

实现方法一:

通过深层重写clone方法来实现深拷贝

在浅拷贝的基础上,如果被拷贝对象有自定义对象属性,则也要到该属性类里进行依次实现Cloneable接口进行重写,重写方法和浅拷贝一样,一直到不再有为止

拷贝时对象A=(对象A)对象B.clone();  因为需要进行强制转换,因此要处理异常,可到重写方法的clone里去捕获异常(默认是抛出)

实现方法二:

通过对象序列化实现深拷贝

如果里面的对象不是基本类型,该类需要实现Serializable
list集合拷贝
    public static <T extends Serializable> List<T> deepCopy(List<T> src) {
        try {
            ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
            ObjectOutputStream out = new ObjectOutputStream(byteOut);
            out.writeObject(src);
            out.flush();
            out.close();
            ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
            ObjectInputStream in = new ObjectInputStream(byteIn);
            @SuppressWarnings("unchecked")
            List<T> dest = (List<T>) in.readObject();
            return dest;
        } catch (IOException ignored) {

        } catch (ClassNotFoundException ignored) {

        }
        return null;

    }
对象拷贝
    public static <T extends Serializable> T deepCopy(T obj) {
        T cloneObj = null;
        try {
            //写入字节流
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(obj);
            oos.close();

            //分配内存,写入原始对象,生成新对象
            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());//获取上面的输出字节流
            ObjectInputStream ois = new ObjectInputStream(bais);

            //返回生成的新对象
            cloneObj = (T) ois.readObject();
            ois.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return cloneObj;
    }

List<Person> destList=deepCopy(srcList);  //调用该方法

Hutool提供了多种对象拷贝的方法,以下是其中两种常用的方法: 1. BeanUtil.copyProperties(source, target) 这是最常用的对象拷贝方法,可以将源对象的属性值拷贝到目标对象中。示例如下: ```java // 定义源对象 public class SourceObject { private String name; private Integer age; // getters/setters } // 定义目标对象 public class TargetObject { private String name; private Integer age; // getters/setters } // 创建源对象 SourceObject source = new SourceObject(); source.setName("Tom"); source.setAge(18); // 创建目标对象 TargetObject target = new TargetObject(); // 拷贝属性值 BeanUtil.copyProperties(source, target); ``` 2. CloneSupport.clone() 这是一个基于反射的对象拷贝方法,可以将一个对象的属性值拷贝到另一个对象中。示例如下: ```java // 定义源对象 public class SourceObject implements Cloneable { private String name; private Integer age; // getters/setters @Override public Object clone() { return CloneSupport.clone(this); } } // 定义目标对象 public class TargetObject { private String name; private Integer age; // getters/setters } // 创建源对象 SourceObject source = new SourceObject(); source.setName("Tom"); source.setAge(18); // 创建目标对象 TargetObject target = new TargetObject(); // 拷贝属性值 CloneSupport.clone(source, target); ``` 需要注意的是,如果要对自定义对象进行拷贝,需要实现Cloneable接口并重写clone()方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值