clone方法的使用
什么是clone()
首先看一下jdk中对clone方法的解释:
看到这里大家可能会很懵逼, 其实clone方法简单来说就是将一个对象的属性和方法都复制一个给另外一个相同类型的对象.注意:复制之后这个对象的地址就和原本对象不同了.
clone的分类
clone 大致分两种,但它们都要实现Cloneable接口,重写clone方法
影子克隆
这个克隆只是简单的将这个对象进行克隆, 不管对象里面有不有引用类的属性, 也就是说,这种克隆 , 它里面的引用类型的成员变量地址还是一样的;
代码分析
public class Person implements Cloneable {
private String name;
private int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
@Override
public boolean equals(Object obj) {
Person p = (Person) obj;
return this.name.equals(p.getName()) && (this.age == p.getAge());
}
@Override
protected Object clone() throws CloneNotSupportedException {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public static void main(String args) throws CloneNotSupportedException {
Person p1 = new Person("小宇", 22);
Person p2 = (Person)p1.clone();
System.out.println(p1 == p2);
System.out.println(p1);
System.out.println(p2);
}
}
运行结果:
可以发现clone的p2 和p1的内容是完全相同
深度克隆
代码分析
public class Person implements Cloneable {
private String name;
private int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
@Override
public boolean equals(Object obj) {
Person p = (Person) obj;
return this.name.equals(p.getName()) && (this.age == p.getAge());
}
@Override
protected Object clone() throws CloneNotSupportedException {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
public class Group implements Cloneable {
private String groupName;
private int groupId;
private Person p;
public Group(String groupName, int groupId, Person p) {
super();
this.groupName = groupName;
this.groupId = groupId;
this.p = p;
}
public String getGroupName() {
return groupName;
}
public void setGroupName(String groupName) {
this.groupName = groupName;
}
public int getGroupId() {
return groupId;
}
public void setGroupId(int groupId) {
this.groupId = groupId;
}
public Person getP() {
return p;
}
public void setP(Person p) {
this.p = p;
}
@Override
public boolean equals(Object obj) {
Group g = (Group) obj;
return (this.groupId == g.groupId) && this.groupName.equals(g.getGroupName()) && this.p.equals(g.getP());
}
@Override
public String toString() {
return "Group [groupName=" + groupName + ", groupId=" + groupId + ", p=" + p + "]";
}
@Override
public Object clone() throws CloneNotSupportedException {
// 深度克隆
Group group = null;
try {
group = (Group) super.clone();
group.p = (Person) this.p.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return group;
}
public static void main(String[] args) throws CloneNotSupportedException {
Group g = new Group("英语学习小组", 1, new Person("小宇", 22));
Group gCopy = (Group)g.clone();
System.out.println(gCopy.equals(g));
System.out.println(g == gCopy);
System.out.println(g);
System.out.println(gCopy);
}
}
运行结果:
可以发现深度克隆不仅仅对Grop进行了克隆, 对立面的Person同样进行了克隆, 也就是说所有的引用类型的地址都发生了改变;
运用
在编程的过程中当我们遇到需要使用一个引用类型, 但又不想去改变里面的内容的时候我们就可以使用克隆.
文章目录
- clone方法的使用
-
- 什么是clone()
- clone的分类
-
- 影子克隆
-
- 代码分析
- 深度克隆
-
- 代码分析
- 运用