Java对象复制:浅拷贝与深拷贝解析
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中复制对象有多种方式,选择哪种取决于具体需求,如对象复杂度、性能考虑以及是否需要深复制等。在实际开发中,可以根据实际情况灵活选用。"
2019-03-30 上传
2020-11-22 上传
2020-12-04 上传
2011-01-12 上传
2019-03-24 上传
2019-03-20 上传
2020-12-22 上传
weixin_38669832
- 粉丝: 5
- 资源: 955
最新资源
- d3-Scatterplot-Graph-fcc:FreeCodeCamp d3散点图
- CG引擎:一个随机的家伙,很开心创建c ++ OpenGl游戏引擎
- Linux shell脚本.rar
- UltrasonicDistanceMeasurementSystem:超声波测距,报警,LCD1602显示数据,温度校正超声波速度
- Excel模板基础体温记录表excel版.zip
- Advanced-Factorization-of-Machine-Systems:GSOC 2017-Apache组织-#使用并行随机梯度下降(python和scala)在Spark上实现分解机器
- operating_system_concept_os
- dosxnt文件-DOS其他资源
- Smart-Device:对于htmlacademy
- static-form-lambda:无服务器模板,创建一个FaaS AWS Lambda来处理表单提交
- Python库 | python-jose-0.6.1.tar.gz
- :scissors: React-Native 组件可在您想要的任何地方切割触摸Kong。 教程叠加的完美解决方案
- ocr
- react-pwa:使用creat js的示例渐进式Web应用程序
- VBiosFinder:从(几乎)任何BIOS更新中提取嵌入式VBIOS
- Python库 | python-hpilo-2.4.tar.gz