java clone()方法理解


首先是java6 api中Cloneable接口的描述

A class implements the Cloneable interface to indicate to the Object.clone() method that it is legal for that method to make a field-for-field copy of instances of that class.Invoking Object's clone method on an instance that does not implement the Cloneable interface results in the exception CloneNotSupportedException being thrown.By convention, classes that implement this interface should override Object.clone (which is protected) with a public method. See Object.clone() for details on overriding this method.Note that this interface does not contain the clone method. Therefore, it is not possible to clone an object merely by virtue of the fact that it implements this interface. Even if the clone method is invoked reflectively, there is no guarantee that it will succeed.

下面是java6 api中对Obejct对象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 x, the expression: x.clone() != xwill be true, and that the expression: x.clone().getClass() == x.getClass()will be true, but these are not absolute requirements. While it is typically the case that: x.clone().equals(x)will be true, this is not an absolute requirement.By convention, the returned object should be obtained by calling super.clone. If a class and all of its superclasses (except Object) obey this convention, it will be the case that x.clone().getClass() == x.getClass().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 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 super.clone need to be modified.The method clone for class Object performs a specific cloning operation. First, if the class of this object does not implement the interface Cloneable, then a CloneNotSupportedException is thrown. Note that all arrays are considered to implement the interface Cloneable. 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.The class Object does not itself implement the interface Cloneable, so calling the clone method on an object whose class is Object will result in throwing an exception at run time.

1.x.clone() != x,意思是clone方法返回的对象是新生成的对象与原来对象的地址不相等。
2. x.clone().getClass() == x.getClass(),两个对象的类是相同的。
3. x.clone().equals(x),这点需要着重说明:这个不是clone方法的绝对要求,这个主要看equals方法的实现。

abstract public class X implements Cloneable { public X clone() throws CloneNotSupportedException { return (X) super.clone(); }}

public Z clone() throws CloneNotSupportedException { Z newZ = (Z) super.clone(); newZ.someABC = someABC.clone(); return newZ;

import java.util.Arrays;/** * * @author lwj.charles * */public class CloneTest {/** * 测试类A */class A implements Cloneable{private int num; //不可变属性,int类型private String str;//不可变属性,String对象是不可修改的。public A(int num, String str){this.num = num;this.str = str;}public A clone() throws CloneNotSupportedException{return (A)super.clone();}public void display(){System.out.println("-----begin-----");System.out.println("int:" + num);System.out.println("String:" + str);System.out.println("-----end-----");}}/** * 测试类B */class B implements Cloneable{private int num; //不可变属性private int [] nums;//可变属性public B(int num, int[] nums){this.num = num;this.nums = nums;}///**// * clone()方法的浅拷贝实现// *///public B clone() throws CloneNotSupportedException{//return (B)super.clone();//}/** * clone()方法的深拷贝实现 */public B clone() throws CloneNotSupportedException{B b = (B)super.clone();b.nums = Arrays.copyOf(b.nums, b.nums.length);return b;}public void display(){System.out.println("-----begin-----");System.out.println("int:" + num);System.out.println("Arrays:" + nums);System.out.println("nums[1]:" + nums[1]);System.out.println("-----end-----");}}public static void main(String [] args) throws CloneNotSupportedException{CloneTest ct = new CloneTest();//测试对象的属性为不可变属性。用浅拷贝即可满足要求。CloneTest.A a1 = A(1,"test1");CloneTest.A a2 = a1.clone();a2.num = 2;a2.str = "test2";a1.display();a2.display();//测试对象的属性为可变属性。注意对比试用浅拷贝和深拷贝的结果。int [] nums = {1,2,3};CloneTest.B b1 = B(1,nums);CloneTest.B b2 = b1.clone();b2.num = 2;b2.nums[1] = -2;b1.display();b2.display();}}