java基础---->Java关于复制的使用(一)
2017-06-22 14:39
357 查看
这里简单记录一下java中关于浅复制和深复制的知识。很多时候,一个人选择了行走,不是因为欲望,也并非诱惑,他仅仅是听到了自己内心的声音。
Thing类实现了Cloneable接口,并重写了Object的clone方法,里面有一个ArrayList列表的私有变量。现在我们的测试代码如下:
运行的结果如下:
从结果我们可以看到:thing.clone()执行并没有再次调用构造函数,复制后的对象和原对象共享私有变量arrayList,也就是说复制对象对arrayList的操作会映射到原对象的arrayList。这样的浅拷贝是有风险的,下面我们介绍一下怎样实现对象的深复制。我们只需要在Thing类中clone方法加上数组的复制代码就可以,clone方法的代码如下:
现在再执行ClientMain的main方法,打印的结果如下:可以看到原对象的arrayList并没有改变。
需要注意的是:对象的clone与对象内的final关键字是有冲突的,我们修改Thing类的私有变量arrayList的修饰符。
通过ide我们可以看到在thing.arrayList = (ArrayList<String>) this.arrayList.clone();代码处会有编译报错。所以要想实现对象的深复制,类的成员变量上不要增加final关键字。
java中的复制clone方法
一、java对象的浅复制
一个实现了Cloneable并重写了clone方法的类A,有一个无参构造或有参构造B,通过new关键字产生了一个对象S,再然后通过S.clone()方式产生了一个新的对象T,那么在对象拷贝时构造函数B是不会被执行的public class Thing implements Cloneable { //定义一个私有变量 private ArrayList<String> arrayList = new ArrayList<String>(); public Thing() { System.out.println("构造函数被执行了......"); } @Override protected Thing clone() { Thing thing = null; try { thing = (Thing) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return thing; } //设置HashMap的值 public void setValue(String value) { this.arrayList.add(value); } //取得arrayList的值 public List<String> getValue() { return this.arrayList; } }
Thing类实现了Cloneable接口,并重写了Object的clone方法,里面有一个ArrayList列表的私有变量。现在我们的测试代码如下:
package com.linux.huhx.learn.clone; /** * @Author: huhx * @Date: 2017-12-26 上午 10:57 */ public class ClientMain { public static void main(String[] args) { // 产生一个对象 Thing thing = new Thing(); thing.setValue("huhx"); // 复制一个对象 Thing cloneThing = thing.clone(); cloneThing.setValue("linux"); System.out.println(thing.getValue()); } }
运行的结果如下:
构造函数被执行了...... [huhx, linux]
从结果我们可以看到:thing.clone()执行并没有再次调用构造函数,复制后的对象和原对象共享私有变量arrayList,也就是说复制对象对arrayList的操作会映射到原对象的arrayList。这样的浅拷贝是有风险的,下面我们介绍一下怎样实现对象的深复制。我们只需要在Thing类中clone方法加上数组的复制代码就可以,clone方法的代码如下:
@Override protected Thing clone() { Thing thing = null; try { thing = (Thing) super.clone(); thing.arrayList = (ArrayList<String>) this.arrayList.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return thing; }
现在再执行ClientMain的main方法,打印的结果如下:可以看到原对象的arrayList并没有改变。
构造函数被执行了...... [huhx]
需要注意的是:对象的clone与对象内的final关键字是有冲突的,我们修改Thing类的私有变量arrayList的修饰符。
private final ArrayList<String> arrayList = new ArrayList<String>();
通过ide我们可以看到在thing.arrayList = (ArrayList<String>) this.arrayList.clone();代码处会有编译报错。所以要想实现对象的深复制,类的成员变量上不要增加final关键字。
Cannot assign a value to final variable 'arrayList'
友情链接
相关文章推荐
- Java基础--->09.关于JDK使用旧方法编译出错、警告问题。
- 【java基础学习-2--】关于Hashcode()的使用
- Java基础--关于static的变量和方法使用的一些不解
- java基础---->string字面量的使用
- java基础---->Java中异常的使用(一)
- Java基础之读文件——使用通道复制文件(FileBackup)
- 使用java语言基础部分知识,做一个简易的2个数之间的关于算术运算符的计算。
- java基础---->java中nio的使用(一)
- Java基础之集合框架——使用堆栈Stack<>对象模拟发牌(TryDeal)
- java基础---->Zip压缩的使用(转)
- 【java基础】关于java使用unicode编码及java编码解码测试数据
- 纠错 : 关于书籍<java核心技术 卷I 基础知识 第八版> 第五章 Employee/Manager 两个例子
- Java基础之IO流,使用字符流缓冲区复制文件
- Java基础之集合框架——使用真的的链表LinkedList<>(TryPolyLine)
- java基础---->Zip压缩的使用
- java基础---->final关键字的使用
- java基础---->数组的基础使用(一)
- java基础---->Base64算法的使用