51

问题:

package GoodQuestions;
public class MyClass {  
    MyClass() throws CloneNotSupportedException {
        try {
            throw new CloneNotSupportedException();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }   

    public static void main(String[] args) {    
        try {
            MyClass  obj = new MyClass();
            MyClass obj3 = (MyClass)obj.clone();            
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

这里类'MyClass'可以通过调用'Object'类中的clone方法来克隆它自己的对象。当我尝试在同一个包'GoodQuestions'中的另一个类('TestSingleTon')中克隆这个类('MyClass')时,它会引发以下编译时错误。

'来自 Object 类型的方法 clone() 不可见'

那么这是引发上述错误的代码吗?

package GoodQuestions;
public class TestSingleTon {
    public static void main(String[] args) {
        MyClass  obj = new MyClass();
        MyClass obj3 = obj.clone(); ---> here is the compile error.
    }
}
4

8 回答 8

49

clone()具有受保护的访问权限。添加这个MyClass

public Object clone(){  
    try{  
        return super.clone();  
    }catch(Exception e){ 
        return null; 
    }
}

也改为 public class MyClass implements Cloneable

于 2011-02-25T10:59:45.457 回答
13

发生此错误是因为在 Object 类中 clone() 方法受到保护。所以你必须在各自的类中覆盖 clone() 方法。例如。在 MyClass 中添加以下代码

@Override
protected Object clone() throws CloneNotSupportedException {

    return super.clone();
}

还实现了 Cloneable 接口。例如。public class MyClass implements Cloneable

于 2016-07-28T09:12:18.890 回答
3

因为 clone() 是一个受保护的方法。有关详细信息,请参阅Object.clone()

覆盖 MyClass 中的 clone() 并使该类实现Cloneable接口。

于 2011-02-25T10:54:10.907 回答
2

微妙之处在于 的clone()方法MyClass是继承的,而不是在MyClass. 所以MyClass可以调用clone()Object ,因为它是protected,但MyClass实际上并没有a ofclone()本身,所以TestSingleTon不能访问clone()ofMyClass因为没有clone()方法。尽管它们都在同一个包中,但您需要在其中定义一个clone()方法MyClass以确保它确实“具有” clone(). 顺便说一句,不要忘记CloneableMyClass.

于 2016-06-25T16:11:57.457 回答
2

Object.clone()方法具有受保护的访问权限,意思是it's visible to sub-classes and classes in the same package

最好有一个用于手动复制对象的复制构造函数。

/**
    Deep copy all the information from other to this
*/
public MyClass (MyClass  other) {
     this.id = other.id;
}

阅读Josh Bloch 为什么使用复制构造函数

于 2018-06-11T13:01:23.050 回答
0

你只需要让 MyClass 实现 Cloneable 接口。无需为 clone() 提供实现。

于 2011-05-14T12:42:32.687 回答
-1

为了能够克隆 MyClass,它必须实现 Cloneable 接口

于 2011-02-25T10:54:39.757 回答
-1

我对此做了一些测试代码,这是我的发现:

当一个受保护的成员被跨包继承时,它成为继承类的私有成员

然而

当受保护的成员在同一个包中被继承时,它成为继承类的默认成员。

在您的示例中,来自 Object 类的 clone() 跨包继承到 MyClass 中。对象类在 java.lang 包中,MyClass 在 GoodQuestions 包中。因此 clone() 方法成为 MyClass 类的私有成员。

这就解释了为什么您无法从 TestSingleTon 类访问 clone() 方法。

于 2013-02-23T04:32:34.890 回答