对象中的方法 clone() 不可见?
Posted
技术标签:
【中文标题】对象中的方法 clone() 不可见?【英文标题】:The method clone() from object is not visible? 【发布时间】:2011-07-04 05:29:14 【问题描述】:问题:
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.
【问题讨论】:
【参考方案1】:clone()
具有受保护的访问权限。将此添加到MyClass
public Object clone()
try
return super.clone();
catch(Exception e)
return null;
也改为public class MyClass implements Cloneable
【讨论】:
我假设受保护的修饰符意味着包级别以及子类。 Java中的每个类不都是Object的子类吗?你的回答是对的,所以我在这里误解了什么? @Justin:是的,它意味着包级别以及子类。所以在你的子类“MyClass”中,它是可见的。但它对“TestSingleTon”不可见,它既不是同一个包也不是子类。 @KarthikBose 因此,这意味着同一子类对象可以在子类中调用受保护的方法。在任何子类中,我们不能用其他子类对象来调用它,例如在这种情况下 clone() 是由 TestSingleton 中的 MyClass 对象调用的? @KarthikBose 因此,来自link 声明“受保护的修饰符指定该成员只能在其自己的包中访问(与包私有一样),此外,还可以通过它的类在另一个包中。”需要更多澄清说明。 在一个类中,如果我在主对象内创建 o = new Object(); o.clone();如果我在我的班级中也覆盖了 clone(),那么 clone() 是不可见的,我得到了【参考方案2】:发生此错误是因为在 Object 类中 clone() 方法受到保护。 所以你必须在各自的类中覆盖 clone() 方法。 例如。在 MyClass 中添加以下代码
@Override
protected Object clone() throws CloneNotSupportedException
return super.clone();
还实现了 Cloneable 接口。
例如。 public class MyClass implements Cloneable
【讨论】:
小心 return super.clone() 可能不够【参考方案3】:因为 clone() 是一个受保护的方法。详情请见Object.clone()。
重写 MyClass 中的 clone() 并使该类实现 Cloneable 接口。
【讨论】:
【参考方案4】:微妙之处在于MyClass
的clone()
方法是继承的,而不是在MyClass
中定义的。所以MyClass
可以调用对象的clone()
,因为它是受保护的,但是MyClass
本身并没有真正拥有 clone()
,所以@987654328 @ 无法访问 MyClass
的 clone()
,因为没有 clone()
方法。尽管它们都在同一个包中,但您需要在MyClass
中定义一个clone()
方法以确保它确实“具有”clone()
。对了,别忘了为MyClass
实现接口Cloneable
。
【讨论】:
【参考方案5】: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;
阅读Why a copy constructor from Josh Bloch
【讨论】:
【参考方案6】:你只需要让 MyClass 实现 Cloneable 接口。无需为 clone() 提供实现。
【讨论】:
问题与Cloneable
无关,如果您希望clone()
成为public
方法(这就是问题 的实际意义),你确实必须提供你自己的实现。【参考方案7】:
为了让你能够克隆 MyClass,它必须实现 Cloneable 接口
【讨论】:
这不能回答问题。问题中的示例已经实现了 Cloneable。它询问由于clone()
是protected
方法而导致的编译错误。【参考方案8】:
我对此做了一些测试代码,这是我的发现:
当一个受保护的成员被跨包继承时,它成为继承类的私有成员
而
当一个受保护的成员在同一个包中被继承时,它成为被继承类的默认成员。
在您的示例中,来自 Object 类的 clone() 跨包继承到 MyClass 中。 对象类在 java.lang 包中,MyClass 在 GoodQuestions 包中。 所以 clone() 方法成为 MyClass 类的私有成员。
这解释了为什么您无法从 TestSingleTon 类访问 clone() 方法。
【讨论】:
我不认为你的理论是正确的。我做了以下事情:- 1) 创建了名为 Parent 的类,使用名为 callProtected() 的受保护方法 2) 在名为 Person 的不同包中创建了另一个类,它扩展了 Parent 类 3) 在同一个名为 Student 的 Person 类包中创建了另一个类extends Person 所以,根据你的理论,如果不同包中的受保护成员变为私有,那么我不应该能够访问 Student 类中的 callProtected 方法,但不幸的是,我可以访问 callProtected 方法。以上是关于对象中的方法 clone() 不可见?的主要内容,如果未能解决你的问题,请参考以下文章