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; }
同样的main函数输出结果就会变为:
原来的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]]
深克隆和浅克隆明显的区别就是:
克隆的对象是不是影响到真正的对象的某些值。
深克隆不会影响到,浅克隆会影响到。