clone常见的三种方式
来源:互联网 发布:武神赵子龙辅助软件 编辑:程序博客网 时间:2024/06/05 14:38
在JAVA中克隆一个对象常见的有三种形式
1.通过自己写一个克隆方法里面 new 一个同样的对象来进行 get、set 依次赋值实现深度克隆(很繁琐且易出错);
2.通过实现 Cloneable 接口并重写 Object 类的 clone() 方法(分为深浅两种方式);
3.通过实现 Serializable 接口并用对象的序列化和反序列化来实现真正的深度克隆;
第一种方法并没有什么卵用
Cloneable 接口实现浅克隆
public class People implements Cloneable { private String name = "ilt"; private Hand hand = new Hand(); public Hand getHand() { return hand; } @Override protected Object clone() throws CloneNotSupportedException { // TODO Auto-generated method stub return super.clone(); } public static void main(String[] args) throws CloneNotSupportedException { People p1 = new People(); People p2 = (People) p1.clone(); System.out.println("第一个对象的hash值:"+p1.hashCode()); System.out.println("第二个对象的hash值:"+p2.hashCode()); System.out.println("分割线-----------"); System.out.println("p1中的hand对象的hash值:"+p1.getHand().hashCode()); System.out.println("p2中的hand对象的hash值:"+p2.getHand().hashCode()); }}class Hand implements Cloneable {}
上面代码输出的结果如下,根据hash值相等能确定两个对象是否相等的原则,发现p1和p2不等,但p1中的hand对象与p2中的hand对象是相等的。Cloneable 接口实现克隆是先在内存中开辟一块和原始对象一样的空间,然后原样拷贝原始对象中的内容,对基本数据类型就是值复制,而对非基本类型变量保存的仅仅是对象的引用,所以会导致 clone 后的非基本类型变量和原始对象中相应的变量指向的是同一个对象。
第一个对象的hash值:1408448235第二个对象的hash值:77244764分割线-----------p1中的hand对象的hash值:1172625760p2中的hand对象的hash值:1172625760
Cloneable 接口实现深克隆
在浅度克隆的基础上对于要克隆对象中的非基本数据类型的属性对应的类也实现克隆,这样对于非基本数据类型的属性复制的不是一份引用。
public class People implements Cloneable { private String name = "ilt"; private Hand hand = new Hand(); public Hand getHand() { return hand; } public void setHand(Hand hand) { this.hand = hand; } @Override protected Object clone() throws CloneNotSupportedException { // TODO Auto-generated method stub People p2 = (People) super.clone(); p2.setHand((Hand) hand.clone()); return p2; } public static void main(String[] args) throws CloneNotSupportedException { People p1 = new People(); People p2 = (People) p1.clone(); System.out.println("第一个对象的hash值:" + p1.hashCode()); System.out.println("第二个对象的hash值:" + p2.hashCode()); System.out.println("分割线-----------"); System.out.println("p1中的hand对象的hash值:" + p1.getHand().hashCode()); System.out.println("p2中的hand对象的hash值:" + p2.getHand().hashCode()); }}class Hand implements Cloneable { @Override protected Object clone() throws CloneNotSupportedException { // TODO Auto-generated method stub return super.clone(); }}
结果如下,证明已经进行深克隆
第一个对象的hash值:1172625760第二个对象的hash值:863719801分割线-----------p1中的hand对象的hash值:1696725334p2中的hand对象的hash值:427340025
序列化与反序列化实现深克隆
对象序列化操作可以将对象的状态转换成字节流传输或者存储再生,我们可以借用这一特点实现对象的深度克隆,特别是当我们的对象嵌套非常复杂且想实现深度克隆时如果使用序列化方式会大大减少代码量。
public class TestClone implements Serializable{ private static final long serialVersionUID = 1L; public String name = "ilt"; public static void main(String[] args) throws Exception { TestClone t1 = new TestClone(); byte[] b = ObjectUtil.objectToBytes(t1);//序列化 TestClone t2 = (TestClone) ObjectUtil.bytesToObject(b);//反序列化 System.out.println("t1对象的name:"+t1.name); System.out.println("t2对象的name:"+t2.name); System.out.println("分割线-------------"); System.out.println("t1对象的hash值为:"+t1.hashCode()); System.out.println("t2对象的hash值为:"+t2.hashCode()); System.out.println("分割线-------------"); System.out.println("t1中的obj对象的hash值为:"+t1.obj.hashCode()); System.out.println("t2中的obj对象的hash值为:"+t2.obj.hashCode()); } class Bean implements Serializable{ private static final long serialVersionUID = 1L; }}
结果如下`,证明对象的属性被深克隆下来了
t1对象的name:iltt2对象的name:ilt分割线-------------t1对象的hash值为:1847546936t2对象的hash值为:812610706分割线-------------t1中的obj对象的hash值为:1164730192t2中的obj对象的hash值为:1699624469
阅读全文
0 0
- clone常见的三种方式
- 数据库常见的三种join方式
- 数据库常见的三种join方式
- 存储整合的常见三种方式
- 常见xml的三种解析方式的区别
- JAVA中常见的三种打印异常的方式
- 三种常见的部署Kubernetes的方式
- 技术文章 | 三种常见的部署Kubernetes的方式
- js对象实例化的常见三种方式
- Android-ListView优化常见的三种方式
- 创业公司股权激励的三种常见方式
- JavaScript 创建对象的常见三种方式
- 警告框的常见三种书写方式
- C++对象之间通信的三种常见方式
- 三种常见组网方式比较
- java使用递归,非递归方式实现二叉树的三种常见遍历方式
- java使用递归,非递归方式实现二叉树的三种常见遍历方式
- js 函数定义的三种方式以及匿名的自执行函数定义方式和常见的错误写法
- hdu 1517 博弈
- 第二十九天 数据库(中)表操作
- Mybatis基本配置
- [51NOD](1001)数组中和等于K的数对 ---二分查找
- Linux系统之ftp
- clone常见的三种方式
- 模板
- 【hdu 1233】 还是畅通工程
- 关于开发者测试
- 性能监控工具
- 洛谷 P3093 牛奶调度Milk Scheduling
- alter database create datafile ......
- QT多线程简单例子
- spfa模板