2011-02-23 39 views
3

这是我无法理解的东西。从java.lang.Object访问clone()

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

这里Sample类是在另一个包中,显然它不能从Object类访问clone()。但由于Sample隐含地从Object派生,为什么它无法访问它?该定义并没有说它必须满足这两个条件(在同一个包中,也是一个子类)。

public class Sample { 

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

回答

9

在你的情况,因为你不是在一个子类调用它的clone()方法是不可见的。 Sample来自Object,所以它可以访问自己的clone()方法,但不能访问其他对象。

对象clone()被设计了几个错误。因此,它是不使用它一个很好的做法 - 这是很难得到正确的事:

  • 的假设是,并不是每一个对象在默认情况下可克隆
  • 如果重写clone()使其成为公共的,它会仍然失败,因为每个类必须实现Cloneable
  • Cloneable,但是,没有定义任何方法,因此对象的用户不能将其引用为Cloneable并期望克隆方法。
  • 在每一个类中必须调用super.clone()默认克隆的工作机制

检查this question替代品。

0

someObject的班级类型在这里很重要。对象someObject可能不会覆盖Object类的clone()方法,从而使类Sample不可见。

0

你是什么意思“无法访问它”?你的意思是它不会编译,或者你的意思是它会抛出CloneNotSupportedException异常。如果你的类没有实现Cloneable接口,则会抛出。

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的实例上调用对象的克隆方法会导致抛出异常CloneNotSupportedException


@Bozho's answer是真的在这里正确的答案,虽然。 只要不使用Object.clone()

Effective Java, Item 10: Override clone judiciously(在以后的版本项目11)。