从java.lang.Object访问clone()

时间:2011-02-23 14:57:13

标签: java oop clone access-modifiers

这是我无法理解的事情。

java.lang.Object中,clone()定义为protected修饰符。根据定义,它可以通过名称在其自己的类定义中访问,通过名称在从它派生的任何类中,以及在同一包中任何类的定义中的名称。

此处Sample类位于另一个包中,显然无法从clone()类访问Object。但是,Sample隐式地从Object派生,为什么它无法访问它?该定义并未说明它必须满足两个条件(在同一个包内,也是一个子类)。

public class Sample {

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

4 个答案:

答案 0 :(得分:9)

在您的情况下,clone()方法不可见,因为您没有从子类中调用它。 Sample来自Object,因此它可以访问自己的clone()方法,但不能访问其他对象。

对象clone()设计有几个错误。所以使用它并不是一个好习惯 - 很难做到正确:

  • 假设默认情况下不是每个对象都是可克隆的
  • 如果您覆盖clone()将其公开,则仍然会失败,因为每个类都必须实现Cloneable
  • 但是,
  • Cloneable没有定义任何方法,因此对象的用户不能将其称为Cloneable并期望克隆方法。
  • 层次结构中的每个类都必须调用super.clone()才能使默认克隆机制正常工作

检查this question是否有替代方案。

答案 1 :(得分:3)

适合我: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();
    }
}

编译时没有错误。它仍会抛出运行时CloneNotSupportedException,因为Main未实现Cloneable

  

一个类实现Cloneable接口,以向Object.clone()方法指示该方法合法地为该类的实例创建一个字段的副本。

     

在未实现Cloneable接口的实例上调用Object的clone方法会导致抛出异常CloneNotSupportedException


不过,

@Bozho's answer确实是正确的答案。 请勿使用Object.clone()

请参阅Effective Java, Item 10: Override clone judiciously(后续版本中的第11项)。

答案 2 :(得分:0)

此类someObject的类类型很重要。对象someObject可能不会覆盖clone()类的Object方法,因此对类Sample不可见。

答案 3 :(得分:0)

你的意思是“无法访问它”?你的意思是它不会编译,或者你的意思是它抛出CloneNotSupportedException。

如果您的类没有实现Cloneable接口,

Object.clone()将抛出CloneNotSupportedException