Java对象复制:浅拷贝与深拷贝解析

1 下载量 15 浏览量 更新于2024-09-02 收藏 101KB PDF 举报
"Java对象的复制主要有三种方式:通过属性逐个赋值、重写`clone()`方法以及使用Apache Commons的工具类BeanUtils和PropertyUtils。以下是对这三种方式的详细解释。 1、通过属性逐个赋值 这种方式是最基础的复制方法,适用于属性较少的对象。例如,在`Student`类只有一个`number`属性的情况下,可以创建一个新的`Student`对象`stu2`,然后通过`setNumber()`方法将`stu1`的`number`值赋给`stu2`: ```java Student stu1 = new Student(); stu1.setNumber(12345); Student stu2 = new Student(); stu2.setNumber(stu1.getNumber()); ``` 这样,即使之后修改`stu1`的属性,也不会影响到`stu2`。 2、重写`clone()`方法 Java中的`Object`类提供了`clone()`方法,但是默认的`clone()`只能实现浅复制,即复制对象时,如果对象内部还包含其他对象,这些内部对象只会复制引用,而非整个对象。因此,如果需要深复制,需要重写`clone()`方法。对于`Student`类,可以这样做: ```java @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } ``` 然后调用`clone()`方法复制对象: ```java Student stu1 = new Student(); stu1.setNumber(12345); Student stu2 = (Student) stu1.clone(); ``` 这样,`stu2`就是一个完全独立的副本,修改`stu1`不会影响`stu2`。 3、使用Apache Commons工具类 Apache Commons提供了BeanUtils和PropertyUtils工具类,可以方便地进行对象复制。首先,需要引入Apache Commons库,然后可以这样复制对象: ```java import org.apache.commons.beanutils.BeanUtils; // ... Student stu1 = new Student(); stu1.setNumber(12345); Student stu2 = new Student(); try { BeanUtils.copyProperties(stu2, stu1); } catch (Exception e) { e.printStackTrace(); } ``` 或使用`PropertyUtils`: ```java import org.apache.commons.beanutils.PropertyUtils; // ... Student stu1 = new Student(); stu1.setNumber(12345); Student stu2 = new Student(); try { PropertyUtils.copyProperties(stu2, stu1); } catch (Exception e) { e.printStackTrace(); } ``` 这两种工具类方法都是基于反射实现的,可以自动处理对象的所有属性复制,包括嵌套的对象。 4、通过序列化实现对象复制 序列化是一种将对象转换为字节流,然后再恢复为对象的过程。可以利用这个特性实现对象复制。首先,让`Student`类实现`Serializable`接口: ```java public class Student implements Serializable { // ... } ``` 然后通过序列化和反序列化完成复制: ```java Student stu1 = new Student(); stu1.setNumber(12345); Student stu2; try ( ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream); ) { objectOutputStream.writeObject(stu1); stu2 = (Student) objectInputStream.readObject(); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } ``` 这种方式也可以实现深复制,但相比前两者,序列化操作的开销较大,通常不作为首选。 总结来说,Java中复制对象有多种方式,选择哪种取决于具体需求,如对象复杂度、性能考虑以及是否需要深复制等。在实际开发中,可以根据实际情况灵活选用。"