从java.lang.Object访问clone()方法

5
这是我无法理解的问题。
在java.lang.Object中,clone()被定义为protected修饰符。根据定义,它可以通过其自身类定义中的名称、从它派生的任何类中的名称以及在同一包中的任何类的定义中的名称访问。
这里的Sample类位于另一个包中,显然无法从Object类访问clone()。但由于Sample隐式派生自Object,为什么它不能访问它呢?定义并没有说它必须同时满足这两个条件(在同一包中和也是子类)。
public class Sample {

  public Object foo() throws CloneNotSupportedException {
   ... 
   return someObject.clone();
  }
}
4个回答

10
在您的情况下,clone()方法不可见是因为您没有从子类中调用它。 Sample派生自Object,因此它可以访问自己的clone()方法,但不能访问其他对象的方法。 Object clone()存在几个错误。因此,使用它不是一个好习惯——很难正确使用:
  • 假设并非每个对象都默认可克隆
  • 如果您重写clone()使其公开,则仍将失败,因为每个类都必须实现Cloneable
  • Cloneable没有定义任何方法,因此对象的用户无法将其引用为Cloneable并期望克隆方法。
  • 层次结构中的每个类都必须调用super.clone()以使默认的克隆机制生效
请查看此问题以获取替代方案。

3

Works for me: http://ideone.com/eST8Y

import java.util.*;
import java.lang.*;

class Main
{
    public Object foo() throws CloneNotSupportedException
    {
        return this.clone();
    }
    
    public static void main (String[] args) throws java.lang.Exception
    {
        new Main().foo();
    }
}

这段代码在编译时没有错误。 但是由于Main没有实现Cloneable接口,因此仍会抛出CloneNotSupportedException运行时异常。

一个类实现Cloneable接口,表示该类的实例可以通过Object.clone()方法进行逐个字段的复制。

对未实现Cloneable接口的实例调用Object的clone方法将导致抛出CloneNotSupportedException异常。


@Bozho的回答才是正确的答案。 不要使用Object.clone()

请参见Effective Java, Item 10: Override clone judiciously(后续版本中为Item 11)。


0

someObject的类类型在这里很重要。对象someObject可能没有覆盖Object类的clone()方法,因此对于类Sample来说是不可见的。


0
你说的“无法访问它”是什么意思?是指它无法编译,还是指它抛出了CloneNotSupportedException异常?
如果你的类没有实现Cloneable接口,Object.clone()方法会抛出CloneNotSupportedException异常。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接