为什么第一个代码被执行但第二个代码给出了CloneNotSupportedException

时间:2015-05-24 08:34:13

标签: java

class test   {
    public    static void main(String as[]){
       Hello h=new Hello();
       Object obj=h.clone();
       System.out.println(obj==h);
    }
}
class Hello{
    protected Object clone(){
        return this;
    }
}

它没有实现接口

但是这段代码:

class test23 {
    public static void main(String as[]) throws Exception {
        Hello23 h1 = new Hello23(99);
        Object h2 = h1.clone();
        System.out.println(h1 == h2);
    }
}

class Hello23 {
    int a;

    Hello23(int a) {
        this.a = a;
    }

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

投掷CloneNotSupportedException

2 个答案:

答案 0 :(得分:3)

您可能认为您的代码正在运行,但事实上并非如此。

它实际上并不创建对象的克隆。这是一个简单的方法恰好被称为clone(),它返回对同一对象的引用。

如果实际上是克隆了对象,那么你应该从比较中得到false,因为克隆是一个新的独立对象,因此对它的引用与对原始对象的引用不同

因此,对于恰好被称为clone但也可能被称为giveMeAReference的方法,Cloneable接口没有问题。它只是调用方法并返回结果。结果是对象的克隆,因此不符合Cloneableclone()合同。

但如果您的clone方法调用super.clone()

,会发生什么?

超类是Object。 Object有一个clone()方法,可以从其子类访问。但是这个方法的作用是首先检查当前对象是否实现了Cloneable接口。

由于您的课程没有,CloneNotSupportedException引发了Object.clone()异常。如果你的类声明了自己implements Cloneable,那么检查将在Object.clone()中传递,因此super.clone()将返回实际对象的本机克隆,并且不会抛出任何异常。

这里的关键是,如果你实际上没有调用super.clone(),那么你实际上并没有通过克隆机制,而你的方法只是违反clone()契约的简单方法。

答案 1 :(得分:0)

Hello调用clone方法时,它会返回此对象的引用,当使用==比较对象时,它会比较是否引用是相等的。对于clone方法,只返回Hello对象的引用,因此它们应该相等。

对于Cloneable类,它不包含clone方法,它只是表示可以克隆此类(逐个字段),因此您必须覆盖clone你班上的方法。