本帖最后由 yqw_gz_java 于 2019-12-3 15:07 编辑
在实际编程过程中,我们常常要遇到这种情况:有一个对象A,在某一时刻A中已经包含了一些有效值,此时可能 会需要一个和A完全相同新对象B,并且此后对B任何改动都不会影响到A中的值,也就是说,A与B是两个独立的对象,但B的初始值是由A对象确定的。这里就要用到java中克隆的知识了.
克隆包括:浅克隆 和深度克隆
一 :如果 A对象的组成都是基本数据类型,只要浅克隆即可.
尺寸类:
[Java] 纯文本查看 复制代码 package cn.yqw.shallowclone;
/**
* @author: 杨钦炜
* @mail [url=mailto:4024081418@qq.com]4024081418@qq.com[/url]
* @create: 2019-12-03 14:47
*/
public class Measurement implements Cloneable {
public int length;
public int width;
public Measurement(int length, int width) {
this.length = length;
this.width = width;
}
@Override
public String toString() {
return "Measurement{" +
"length=" + length +
", width=" + width +
'}';
}
@Override
protected Measurement clone() {
Measurement clone = null;
try {
clone = (Measurement) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return clone;
}
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
}
测试类:
[Java] 纯文本查看 复制代码 package cn.yqw.shallowclone;
/**
* @author: 杨钦炜
* @mail [url=mailto:4024081418@qq.com]4024081418@qq.com[/url]
* @create: 2019-12-03 14:52
*/
public class Test1 {
public static void main(String[] args) {
Measurement m1 = new Measurement(10, 20);
Measurement m2 = m1.clone();
m2.length=128;
m2.width=100;
System.out.println("m2:==>"+m2);
System.out.println("m1:==>"+m1);
}
}
输出效果:
[AppleScript] 纯文本查看 复制代码 C:\java8\bin\java.exe "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2019.2.4\lib\idea_rt.jar=2098:C:\Program Files\JetBrains\IntelliJ IDEA 2019.2.4\bin" -Dfile.encoding=UTF-8 -classpath C:\java8\jre\lib\charsets.jar;C:\java8\jre\lib\deploy.jar;C:\java8\jre\lib\ext\access-bridge-64.jar;C:\java8\jre\lib\ext\cldrdata.jar;C:\java8\jre\lib\ext\dnsns.jar;C:\java8\jre\lib\ext\jaccess.jar;C:\java8\jre\lib\ext\jfxrt.jar;C:\java8\jre\lib\ext\localedata.jar;C:\java8\jre\lib\ext\nashorn.jar;C:\java8\jre\lib\ext\sunec.jar;C:\java8\jre\lib\ext\sunjce_provider.jar;C:\java8\jre\lib\ext\sunmscapi.jar;C:\java8\jre\lib\ext\sunpkcs11.jar;C:\java8\jre\lib\ext\zipfs.jar;C:\java8\jre\lib\javaws.jar;C:\java8\jre\lib\jce.jar;C:\java8\jre\lib\jfr.jar;C:\java8\jre\lib\jfxswt.jar;C:\java8\jre\lib\jsse.jar;C:\java8\jre\lib\management-agent.jar;C:\java8\jre\lib\plugin.jar;C:\java8\jre\lib\resources.jar;C:\java8\jre\lib\rt.jar;C:\Users\yqw\IdeaProjects\jishutie\target\classes cn.yqw.shallowclone.Test1
m2:==>Measurement{length=128, width=100}
m1:==>Measurement{length=10, width=20}
Process finished with exit code 0
从上面测试效果来看,两个对象已经是互不影响了,接着看下面的列子
现在有学生类,和地址类,clone 一个学生,然后修改地址对象
学生类代码如下:
[Java] 纯文本查看 复制代码 package cn.yqw.clone;
/**
* @author: 杨钦炜
* @mail [url=mailto:4024081418@qq.com]4024081418@qq.com[/url]
* @create: 2019-12-03 13:56
*/
public class Student implements Cloneable {
public String studentname;
public Address address;
public Student(String studentname, Address address) {
this.studentname = studentname;
this.address = address;
}
@Override
protected Student clone(){
Student clone = null;
try {
clone = (Student) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return clone;
}
@Override
public String toString() {
return "Student{" +
"studentname='" + studentname + '\'' +
", address=" + address +
'}';
}
}
地址类代码如下:
[Java] 纯文本查看 复制代码 package cn.yqw.clone;
/**
* @author: 杨钦炜
* @mail [url=mailto:4024081418@qq.com]4024081418@qq.com[/url]
* @create: 2019-12-03 13:57
*/
public class Address {
/**
* 简要
*/
public String brief;
/**
* 详情
*/
public String details;
public Address(String brief, String details) {
this.brief = brief;
this.details = details;
}
@Override
public String toString() {
return "Address{" +
"brief='" + brief + '\'' +
", details='" + details + '\'' +
'}';
}
}
测试类代码如下
[Java] 纯文本查看 复制代码 package cn.yqw.clone;
/**
* @author: 杨钦炜
* @mail [url=mailto:4024081418@qq.com]4024081418@qq.com[/url]
* @create: 2019-12-03 13:58
*/
public class Test {
public static void main(String[] args) {
Student student = new Student("学生一",new Address("湖南","湖南省邵阳市新宁县丰田乡"));
Student clone = student.clone();
System.out.println(clone);
clone.address.brief="广州";
clone.address.details="广东省广州市天河区";
System.out.println("-----------------------------------");
System.out.println("clone:===>"+clone);
System.out.println("student:===>"+student);
}
}
输出效果
Student{studentname='学生一', address=Address{brief='湖南', details='湖南省邵阳市新宁县丰田乡'}}
-----------------------------------
clone:===>Student{studentname='学生一', address=Address{brief='广州', details='广东省广州市天河区'}}
student:===>Student{studentname='学生一', address=Address{brief='广州', details='广东省广州市天河区'}}
从上面的测试来看,对学生二做修改影响到了学生一,这不是我们想要的结果,接下来就要用我深度克隆来解决这个问题
修改地址类:
[Java] 纯文本查看 复制代码 package cn.yqw.clone;
/**
* @author: 杨钦炜
* @mail [email]4024081418@qq.com[/email]
* @create: 2019-12-03 13:57
*/
public class Address implements Cloneable{
/**
* 简要
*/
public String brief;
/**
* 详情
*/
public String details;
public Address(String brief, String details) {
this.brief = brief;
this.details = details;
}
@Override
protected Address clone() {
Address clone = null;
try {
clone = (Address) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return clone;
}
@Override
public String toString() {
return "Address{" +
"brief='" + brief + '\'' +
", details='" + details + '\'' +
'}';
}
}
学生类修改如下:
[Java] 纯文本查看 复制代码 package cn.yqw.clone;
/**
* @author: 杨钦炜
* @mail [email]4024081418@qq.com[/email]
* @create: 2019-12-03 13:56
*/
public class Student implements Cloneable {
public String studentname;
public Address address;
public Student(String studentname, Address address) {
this.studentname = studentname;
this.address = address;
}
@Override
protected Student clone() {
Student clone = null;
try {
clone = (Student) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
clone.address = clone.address.clone();
return clone;
}
@Override
public String toString() {
return "Student{" +
"studentname='" + studentname + '\'' +
", address=" + address +
'}';
}
}
测测试结果:
[AppleScript] 纯文本查看 复制代码 Student{studentname='学生一', address=Address{brief='湖南', details='湖南省邵阳市新宁县丰田乡'}}
-----------------------------------
clone:===>Student{studentname='学生一', address=Address{brief='广州', details='广东省广州市天河区'}}
student:===>Student{studentname='学生一', address=Address{brief='湖南', details='湖南省邵阳市新宁县丰田乡'}}
总结:当被克隆的对象存在引用类型的属性,就要用到深度克隆.
|
|