日期:2014-05-20  浏览次数:21120 次

Java 如何复制对象(不是复制引用)
Java code

public class CloneTest {
    public static void main(String[] args) {
        A a = new A();
        A b = new A(3);
        System.out.println(a.i);
        System.out.println(b.i);
        a = b.clone();
        System.out.println(a.i);
        b.i = 5;
        System.out.println(b.i);
        System.out.println(a.i);
    }
}

class A implements Cloneable {
    int i = 0;

    A() {
    }

    A(int i) {
        this.i = i;
    }

    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}



运行时, 会出错, 错误信息如下:
C/C++ code

/*
CloneTest.java:7: 不兼容的类型
找到: java.lang.Object
需要: A
        a = b.clone();
                   ^
1 错误
*/


  
  为什么错了? 怎么改?

------解决方案--------------------
super.clone()返回的是父类的克隆对象(也就是Object对象),不是子类的克隆对象,所以强行转换就会失败
Java code
public Object clone() throws CloneNotSupportedException {
    //return super.clone();
    //如果是浅克隆
    return this; //直接返回对象本身
    //如果是深克隆
    //return new A(this.i); //重新生成一个对象,并用当前对象的属性初始化新对象
}

------解决方案--------------------
Java code

public class CloneTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        A a = new A();
        A b = new A(3);
        System.out.println(a.i);
        System.out.println(b.i);
        a = (A)b.clone();//要强转
        System.out.println(a.i);
        b.i = 5;
        System.out.println(b.i);
        System.out.println(a.i);
    }
}

class A implements Cloneable {
    int i = 0;
    A() {
    }
    A(int i) {
        this.i = i;
    }
    
    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

------解决方案--------------------
克隆方法是先调用父类的clone方法,再将本类对象的属性赋给要克隆的对象
Java code

public class Test implements Cloneable
{
    int a = 0;

    public static void main(String[] args) throws Exception
    {
    Test t = new Test();
    t.a = 123;
    Test t1 = (Test) t.clone();
    System.out.println(t1 == t);
    System.out.println(t1.a);
    }

    @Override
    public Object clone()
    {
    try
    {
        Test t = (Test) super.clone();
        t.a = this.a;
        return t;
    }
    catch (CloneNotSupportedException e)
    {
        // this shouldn't happen, since we are Cloneable
        throw new InternalError();
    }
    }
}

------解决方案--------------------
一个简单的编译错误,clone方法返回的是Object,你却把它赋值给A类的一个对象,所以需要强转一下:
Java code

try{
a = (A)b.clone();
}catch(CloneNotSupportedException e){
  e.printStackTrace();
}