jdk 1.6 中Object的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 <tt>x</tt>, 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 <tt>true</tt>, but these are not absolute requirements.
* While it is typically the case that:
* <blockquote>
* <pre>
* x.clone().equals(x)</pre></blockquote>
* will be <tt>true</tt>, this is not an absolute requirement.
* <p>
* By convention, the returned object should be obtained by calling
* <tt>super.clone</tt>. If a class and all of its superclasses (except
* <tt>Object</tt>) obey this convention, it will be the case that
* <tt>x.clone().getClass() == x.getClass()</tt>.
* <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 <tt>super.clone</tt> 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 <tt>super.clone</tt>
* need to be modified.
* <p>
* The method <tt>clone</tt> for class <tt>Object</tt> performs a
* specific cloning operation. First, if the class of this object does
* not implement the interface <tt>Cloneable</tt>, then a
* <tt>CloneNotSupportedException</tt> is thrown. Note that all arrays
* are considered to implement the interface <tt>Cloneable</tt>.
* 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 <tt>Object</tt> does not itself implement the interface
* <tt>Cloneable</tt>, so calling the <tt>clone</tt> method on an object
* whose class is <tt>Object</tt> will result in throwing an
* exception at run time.
*
* @return a clone of this instance.
* @exception CloneNotSupportedException if the object's class does not
* support the <code>Cloneable</code> interface. Subclasses
* that override the <code>clone</code> method can also
* throw this exception to indicate that an instance cannot
* be cloned.
* @see java.lang.Cloneable
*/
protected native Object clone() throws CloneNotSupportedException;
(1)创建一个对象的副本。
(2)这个对象所对应的类必须实现Cloneable接口,否则的话会抛出CloneNotSupportException异常。
(3)克隆有浅克隆和深克隆的说法,默认的是浅克隆。
浅克隆:
package com.panpass.main;
public class Student {
private String name;
private int age;
public Student(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 "Student [name=" + name + ", age=" + age + "]";
}
}
package com.panpass.main;
public class Person implements Cloneable{
private String name;
private int age;
private Student student;
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;
}
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
public Person(String name, int age, Student student) {
super();
this.name = name;
this.age = age;
this.student = student;
}
@Override
public Object clone(){
Person p = null;
try {
p = (Person) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return p;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", student=" + student
+ "]";
}
}
package com.panpass.main;
import java.util.AbstractMap;
import java.util.AbstractMap.SimpleImmutableEntry;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class Main{
public static void main(String[] args) {
Student student = new Student("st", 11);
Person p = new Person("ldd",23,student);
Person pp = (Person) p.clone();
pp.setName("clone");
Student cloneStudent = pp.getStudent();
cloneStudent.setAge(12);
cloneStudent.setName("clonest");
// pp.setStudent(cloneStudent);
System.out.println("原来的p"+p.toString());
System.out.println("克隆之后的改变值的p"+p.toString());
System.out.println("克隆之后的改变值的pp"+pp.toString());
}
}
输出:
原来的pPerson [name=ldd, age=23, student=Student [name=clonest, age=12]]
克隆之后的改变值的pPerson [name=ldd, age=23, student=Student [name=clonest, age=12]]
克隆之后的改变值的ppPerson [name=clone, age=23, student=Student [name=clonest, age=12]]
深克隆:
只需将Person类中的clone方法改为:
@Override
public Object clone(){
Person p = null;
try {
p = (Person) super.clone();
Student st = p.getStudent();
Student cloneSt = new Student(st.getName(),st.getAge());
p.setStudent(cloneSt);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return p;
}
原来的pPerson [name=ldd, age=23, student=Student [name=st, age=11]]
克隆之后的改变值的pPerson [name=ldd, age=23, student=Student [name=st, age=11]]
克隆之后的改变值的ppPerson [name=clone, age=23, student=Student [name=clonest, age=12]]
深克隆和浅克隆明显的区别就是:
克隆的对象是不是影响到真正的对象的某些值。
深克隆不会影响到,浅克隆会影响到。