【问题标题】:The method clone() from object is not visible?对象中的方法 clone() 不可见?
【发布时间】: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.
    }
}

【问题讨论】:

    标签: java methods clone cloneable


    【解决方案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】:

      微妙之处在于MyClassclone()方法是继承的,而不是在MyClass中定义的。所以MyClass 可以调用对象的clone(),因为它是受保护的,但是MyClass 本身并没有真正拥有 clone(),所以@987654328 @ 无法访问 MyClassclone(),因为没有 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 方法。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-12-29
          • 2012-01-04
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多