java对象拷贝(java对象拷贝 工具类总结)

什么是Java对象拷贝

Java对象拷贝就是指将一个对象的值复制到另一个对象中。Java中有两种对象拷贝方式:浅拷贝和深拷贝。浅拷贝会复制对象的引用,而不会复制对象本身;而深拷贝会复制对象本身,包括它所引用的对象。Java中提供了Cloneable接口和Serializable接口来实现浅拷贝和深拷贝。

浅拷贝与深拷贝

浅拷贝是指复制一个对象,新对象中的所有变量都是对原对象的一个引用,因此,在拷贝后,原对象和新对象的变量指向同一地址,如果一个对象改变了这个地址所存储的内容,另一个对象也会受到影响。例如:

java对象拷贝(java对象拷贝 工具类总结)

public class Teacher implements Cloneable {
    private String name;
    private int age;
    private Student student;

    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    public static void main(String[] args) throws CloneNotSupportedException {
        Teacher teacher = new Teacher();
        teacher.setName("小明");
        teacher.setAge(30);
        Student student = new Student();
        student.setName("张三");
        student.setAge(18);
        teacher.setStudent(student);

        Teacher teacher1 = (Teacher) teacher.clone();

        System.out.println("teacher: " + teacher.hashCode());
        System.out.println("teacher1: " + teacher1.hashCode());

        System.out.println("student: " + teacher.getStudent().hashCode());
        System.out.println("student1: " + teacher1.getStudent().hashCode());

        teacher.getStudent().setName("李四");

        System.out.println("teacher.getStudent(): " + teacher.getStudent().getName());
        System.out.println("teacher1.getStudent(): " + teacher1.getStudent().getName());
    }
}

public class Student implements Cloneable {
    private String name;
    private int age;

    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

上述代码中的Teacher类有一个成员变量Student,在main方法中创建了一个Teacher类型的对象teacher,并将其成员变量student的值设置为另一个Student类型的对象。随后,将teacher对象拷贝到teacher1对象中,并将teacher的student对象的name属性设置为“李四”,最后分别输出teacher对象和teacher1对象的成员变量student的name属性,输出结果如下:

teacher: 267516
teacher1: 81227828
student: 1002270723
student1: 1002270723
teacher.getStudent(): 李四
teacher1.getStudent(): 李四

可以看到,teacher和teacher1的成员变量student指向的是同一个对象,这就导致了当改变teacher对象的成员变量student的name属性时,teacher1对象的成员变量student的name属性也会受到影响。

而深拷贝则是指如果原对象的某一属性是引用类型的,那么新对象的这一属性将指向一个新的引用地址,相当于重新创建了一份原对象的属性,而不是对原来的引用进行复制。如何进行深拷贝?

我们可以通过序列化(serialization)、反序列化(deserialization)来实现深拷贝,序列化和反序列化会在内存中开辟一个新空间,且内存中的新开辟的空间与原本的对象并没有任何关联,需要注意的是深拷贝时,引用的对象也需要实现序列化。如下代码实现深拷贝:

public static  T deepClone(T obj) throws IOException, ClassNotFoundException {
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
    objectOutputStream.writeObject(obj);

    ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
    ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
    return (T) objectInputStream.readObject();
}

上述实现方法使用了Java提供的序列化、反序列化机制,可以比较完美地实现对象的深拷贝。另外,在使用序列化拷贝对象时,我们应该注意避免序列化的对象各种版本不同导致的问题。

使用对象拷贝的注意事项

使用Java对象拷贝需要注意以下几个问题:

  • 对象必须实现Cloneable或Serializable接口,否则拷贝时会抛出异常。
  • 浅拷贝只是拷贝了引用,不会有新的对象产生,所以需要在使用前考虑对象被修改的风险,深拷贝则不存在这个问题。
  • 如果对象中的成员变量是不可变类型,则拷贝时可以不用在意深拷贝浅拷贝的问题;如果是可变类型,则需要考虑使用深拷贝。
  • 序列化、反序列化实现深拷贝时需要注意被序列化的对象需要全部是可序列化的,否则会引发序列化异常。

Java对象拷贝是对一个对象的值进行复制,可以使用浅拷贝和深拷贝来实现。浅拷贝只是复制对象的引用,而深拷贝则是复制整个对象,包括它所引用的对象。Java中提供了Cloneable接口和Serializable接口来实现对象拷贝。使用对象拷贝需要注意对象必须实现Cloneable或Serializable接口,浅拷贝需要注意对象被修改的风险,选择深拷贝还是浅拷贝取决于成员变量的类型,使用序列化拷贝对象时,需要注意被序列化的对象需要全部是可序列化的。

本文来自投稿,不代表亲测学习网立场,如若转载,请注明出处:https://www.qince.net/java1u6java.html

郑重声明:

本站所有内容均由互联网收集整理、网友上传,并且以计算机技术研究交流为目的,仅供大家参考、学习,不存在任何商业目的与商业用途。 若您需要商业运营或用于其他商业活动,请您购买正版授权并合法使用。

我们不承担任何技术及版权问题,且不对任何资源负法律责任。

如遇到资源无法下载,请点击这里失效报错。失效报错提交后记得查看你的留言信息,24小时之内反馈信息。

如有侵犯您的版权,请给我们私信,我们会尽快处理,并诚恳的向你道歉!

(0)
上一篇 2023年4月24日 下午11:30
下一篇 2023年4月24日 下午11:30

猜你喜欢