clone方法的使用
什么是clone()
首先看一下jdk中對clone方法的解釋:
/**
* Creates and returns a copy of this object. The precise meaning
* of "copy" may depend on the class of the object. The general
* intent is that, for any object {@code x}, the expression:
* <blockquote>
* <pre>
* x.clone() != x</pre></blockquote>
* will be true, and that the expression:
* <blockquote>
* <pre>
* x.clone().getClass() == x.getClass()</pre></blockquote>
* will be {@code true}, but these are not absolute requirements.
* While it is typically the case that:
* <blockquote>
* <pre>
* x.clone().equals(x)</pre></blockquote>
* will be {@code true}, this is not an absolute requirement.
* <p>
* By convention, the returned object should be obtained by calling
* {@code super.clone}. If a class and all of its superclasses (except
* {@code Object}) obey this convention, it will be the case that
* {@code x.clone().getClass() == x.getClass()}.
* <p>
* By convention, the object returned by this method should be independent
* of this object (which is being cloned). To achieve this independence,
* it may be necessary to modify one or more fields of the object returned
* by {@code super.clone} before returning it. Typically, this means
* copying any mutable objects that comprise the internal "deep structure"
* of the object being cloned and replacing the references to these
* objects with references to the copies. If a class contains only
* primitive fields or references to immutable objects, then it is usually
* the case that no fields in the object returned by {@code super.clone}
* need to be modified.
* <p>
* The method {@code clone} for class {@code Object} performs a
* specific cloning operation. First, if the class of this object does
* not implement the interface {@code Cloneable}, then a
* {@code CloneNotSupportedException} is thrown. Note that all arrays
* are considered to implement the interface {@code Cloneable} and that
* the return type of the {@code clone} method of an array type {@code T[]}
* is {@code T[]} where T is any reference or primitive type.
* Otherwise, this method creates a new instance of the class of this
* object and initializes all its fields with exactly the contents of
* the corresponding fields of this object, as if by assignment; the
* contents of the fields are not themselves cloned. Thus, this method
* performs a "shallow copy" of this object, not a "deep copy" operation.
* <p>
* The class {@code Object} does not itself implement the interface
* {@code Cloneable}, so calling the {@code clone} method on an object
* whose class is {@code Object} will result in throwing an
* exception at run time.
*
* @return a clone of this instance.
* @throws CloneNotSupportedException if the object's class does not
* support the {@code Cloneable} interface. Subclasses
* that override the {@code clone} method can also
* throw this exception to indicate that an instance cannot
* be cloned.
* @see java.lang.Cloneable
*/
看到這里大家可能會很懵逼, 其實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的分類
- 影子克隆
- 代碼分析
- 深度克隆
- 代碼分析
- 運用
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/206819.html
標籤:python
下一篇:第十四天:執行緒池+執行緒工具類
