Java对象的克隆

Java对象的复制:

1. 浅克隆

拷⻉对象和原始对象的引⽤类型引用同⼀个对象。

方法1:直接赋

Student stu1=new Student();
Student stu2=new Student();
stu2=stu1;

解读:
stu1用new开辟了空间,"stu2=stu1;"意味着把stu1的所指对象的地址传输给stu2;即二者指向同一个对象,所以之后如果改变stu2所指的内容,stu1也改变了。
stu1=stu2

方法2:重写父类Object的clone()方法–implement cloneable

@Override  
public Student clone() throws CloneNotSupportedException {  
            return (Student) super.clone();  
        }  

2. 深克隆

开辟了一片空间,该空间存的内容与要被拷贝的对象的内容完全一致,新的克隆的引用指向这个新的空间,所以当改变这个空间的内容时,原先要被拷贝的对象并没有变化。
即:拷贝对象和原始对象的引用类型引用不同的对象

方法:
A.get,set挨个儿赋值--------->太慢

B.重写父类Object的clone()方法–implement cloneable

假设在Student 的属性里有一个 Address 类
则:
1.Address类实现Cloneable接口,重写clone方法;

 @Override  
public Address clone() throws CloneNotSupportedException {  
    return (Address) super.clone();  
}  

2.在Student类的clone方法中调用Address类的clone方法。

 @Override  
public Student clone() throws CloneNotSupportedException {  
    Student student = (Student) super.clone();  
    student.address = address.clone();  
    return student;  
} 

C.序列化implements Serializable

序列化就是将对象写到流的过程,写到流中的对象是原有对象的一个拷贝,而原对象仍然存在于内存中。通过序列化实现的拷贝不仅可以复制对象本身,而且可以复制其引用的成员对象,因此通过序列化将对象写到一个流中,再从流里将其读出来,可以实现深克隆。需要注意的是能够实现序列化的对象其类必须实现Serializable接口,否则无法实现序列化操作。

序列化中常见的问题:

问题一:static 属性不能被序列化

原因:序列化保存的是对象的状态,静态变量属于类的状态,因此 序列化并不保存静态变量。

问题二:Transient 属性不会被序列化

问题三:序列化版本号serialVersionUID
当我们没定义的时候JDK工具会按照我们对象的属性生成一个对应的版本号。

D. 工具类BeanUtils和PropertyUtils进行对象复制

Student stu1 = new Student();  
stu1.setNumber(12345);  
Student stu2 = new Student(); 
BeanUtils.copyProperties(stu2,stu1);

在实际开发中,BeanUtils使用更普遍一点,犯错的风险更低一点。

总结:

  • 浅克隆

只复制基本类型的数据,引用类型的数据只复制了引用的地址,引用的对象并没有复制,在新的对象中修改引用类型的数据会影响原对象中的引用。
-------不同引用存的同一对象的地址,即指向同一对象。

  • 深克隆

复制后的对象与原对象之间完全不会影响。
-------不同引用存的不同对象的地址,即指向不同对象,即使对象与对象的内容完全相同,但是内存中开辟的空间是不一样的。

  • 使用序列化

使用序列化也能完成深复制的功能:对象序列化后写入流中,此时也就不存在引用什么的概念了,再从流中读取,生成新的对象,新对象和原对象之间也是完全互不影响的。

  • 深克隆重写方法与浅克隆的关系

使用clone实现的深克隆其实是浅克隆中嵌套了浅克隆,与toString方法类似

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值