您的位置:首页 > 编程语言 > Java开发

Java-克隆

2016-05-25 16:11 316 查看
假克隆
1测试代码

2输出结果

3结果分析

浅克隆
1测试代码

2输出结果

3结果分析

深克隆
测试代码

输出结果

结果分析

总结

1.假克隆

1.1测试代码

/**
* 假克隆
* <p>
* 只复制了对象,没有复制对象的引用
*/
private static void testFakeClone() {
//源对象
Bean bean = new Bean("张三", new Boss("老大"));

//这是克隆对象
Bean clone = bean;
clone.setName("小明");
clone.getBoss().setName("头");

System.out.println("这是原始数据:");
System.out.println(JSON.toJSONString(bean));
System.out.println("这是假克隆:");
System.out.println(JSON.toJSONString(clone));
}


1.2.输出结果:

//这是原始数据:

{

“boss”: {

“name”: “头”

},

“name”: “小明”

}

//这是假克隆:

{

“boss”: {

“name”: “头”

},

“name”: “小明”

}

1.3.结果分析:

这里,我们修改了克隆对象的属性之后,源对象的属性也同样变了,关系如图所示(图是盗来的,不要纠结于名称):



2.浅克隆

2.1.测试代码:

/**
* 浅克隆
* <p>
* 既复制了对象,也复制了对象的引用
* 但是如果引用还存在引用,而更深层的引用如果没有实现cloneable接口,就还是会指向源对象
*/
private static void testShallowClone() {
//源对象
Bean bean = new Bean("张三", new Boss("老大"));

//这是克隆对象
Bean clone = bean.clone();
clone.setName("小明");
clone.getBoss().setName("头");

System.out.println("这是原始数据:");
System.out.println(JSON.toJSONString(bean));
System.out.println("这是浅克隆:");
System.out.println(JSON.toJSONString(clone));
}


需要Bean实现Cloneable接口:

/**
* 被克隆对象
* <p>
*/
public static class Bean implements Cloneable {
private String name;
private Boss boss;

public Bean() {
}

public Bean(String name, Boss boss) {
this.name = name;
this.boss = boss;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Boss getBoss() {
return boss;
}

public void setBoss(Boss boss) {
this.boss = boss;
}

@Override
protected Bean clone() {
Bean clone = null;
try {
clone = (Bean) super.clone();

} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
return clone;
}
}


2.2.输出结果:

//这是原始数据:

{

“boss”: {

“name”: “头”

},

“name”: “张三”

}

//这是浅克隆:

{

“boss”: {

“name”: “头”

},

“name”: “小明”

}

2.3.结果分析:

这里,我们修改了克隆对象的属性之后,源对象的name属性没有变,但是更深的引用boss却变了,说明此时源对象和克隆对象所引用的boss对象,其实还是同一个,关系如图所示(图是盗来的,不要纠结于名称):



深克隆

测试代码:

/**
* 深克隆
* <p>
* 将对象序列化,再反序列化生成一个新对象即可
* Serializable、Parcelable、JSON等均可
*/
private static void testDeepClone() {
//源对象
Bean bean = new Bean("张三", new Boss("老大"));

//这是克隆对象
String json = JSON.toJSONString(bean);
Bean clone = JSON.parseObject(json, Bean.class);
clone.setName("小明");
clone.getBoss().setName("头");

System.out.println("这是原始数据:");
System.out.println(JSON.toJSONString(bean));
System.out.println("这是深克隆:");
System.out.println(JSON.toJSONString(clone));
}


输出结果:

//这是原始数据:

{

“boss”: {

“name”: “老大”

},

“name”: “张三”

}

//这是深克隆:

{

“boss”: {

“name”: “头”

},

“name”: “小明”

}

结果分析:



总结:

clone在平时项目中虽然用的不多,但是,区分深克隆和浅克隆却可以帮助我们理解java的内存结构

clone的深克隆其实就是序列化和反序列化,这里有很多种选择,Serializable、Parcelable、JSON等均可

clone方法不同于new方法,不会执行构造方法

参考目录:

1. 详解Java中的clone方法 – 原型模式
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: