10

我正在尝试克隆一个 Integer 类的对象,它确实实现了可克隆接口。

Integer a = new Integer(4);  
Integer b = a.clone();

我知道有解决方法,但我必须像这样实现它。为什么我收到此错误= clone()已保护访问java.lang.Object

为什么会这样说?克隆方法不是可克隆接口的公共抽象方法吗,和对象有什么关系。提前致谢 :-)

4

7 回答 7

17

java.lang.Integers 是不可变的。没有理由克隆一个。如果您浪费内存,请尝试Integer.valueOf(myInteger.intValue()).

于 2011-04-28T07:08:55.463 回答
9

当然,其中的所有方法Object都是继承的。然而,该clone方法是protected,因此只能从子类中访问。

protected 修饰符指定该成员只能在其自己的包中访问(与 package-private 一样),此外,它的类在另一个包中的子类也可以访问。

您可以在大多数其他情况下调用的原因是子类通过使用访问修饰符clone()覆盖它来“打开它” 。public

于 2011-04-28T07:00:50.300 回答
2

出现错误是因为clonejava.lang.Object 的方法不公开可见。

于 2011-04-28T07:00:18.837 回答
2

正如 Amit 和 aioobe 指出的那样,Integer 是不可变的,因此无需克隆它。

但是要回答你的问题。clone() 方法不是可克隆接口的一部分,请参阅:http: //download.oracle.com/javase/6/docs/api/java/lang/Cloneable.html,正如 aioobe 告诉你的那样。

克隆方法在 Object 中声明为受保护的,您必须用公共方法覆盖它才能使用它。见http://download.oracle.com/javase/6/docs/api/java/lang/Object.html#clone ()

简而言之,这样做的原因是,为了克隆一个对象,可能需要也可能不需要进行“深度克隆”,例如。克隆字段及其子元素。或者克隆一个对象可能没有意义,就像 Integer 一样(因为它是不可变的)

于 2011-04-28T08:29:26.220 回答
1

首先,当您不希望其他人更改您的副本时,我需要通过克隆获得副本。现在 Integer 是一个像 String 和 Double 一样的包装类,它们是Immutable。这意味着你不能改变它的内部结构。因此,只要您拥有原始引用,您的对象就完好无损。

Integer a = new Integer(4); // a referencing to this newly Created Integer
    b = a;  // b is referencing to..
    b = new Integer(8) // b no longer references to 4. 
                      //We changed the reference not the internals of it which is impossible.
于 2011-04-28T07:29:19.433 回答
0

可能很难相信,但您的错误是正确的:clone() has protected access in java.lang.Object

于 2011-04-28T09:00:42.823 回答
0

是的,因为 clone() 方法是受保护的,它只能被继承,但你不能在另一个类的对象上调用它。每个类都继承 Object,所以你可以调用 clone()。

但是在(默认/本机)clone() 方法中,您有一个 if(){},如果您的类没有实现 Cloneable,它将抛出异常 CloneNotSupportedException。我说原生是因为 clone() 方法是原生的,当你调用它时,后面会调用另一个用 C++ 编写的方法。

这是调用 clone() 时调用的一小部分代码。

if (!klass->is_cloneable()) {
    ResourceMark rm(THREAD);
    THROW_MSG_0(vmSymbols::java_lang_CloneNotSupportedException(), klass->external_name());
  }

谢谢是否可以找到 Java 本机方法的源代码?

您可以使用反射来调用克隆方法,而无需在对象中覆盖它。

public class Main{
    public static void main(String[] args) throws CloneNotSupportedException {
        A a = new A();
        Object o = new Object();
        Method method = null;
        try {
            method = o.getClass().getDeclaredMethod("clone");
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        method.setAccessible(true);
        try {
            System.out.println(method.invoke(a));
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}

class A implements Cloneable {
}

并被method.invoke(a) instanceof A评估为真

不实施 Cloneable 你会得到

Caused by: java.lang.CloneNotSupportedException: defaultPackage.A
    at java.lang.Object.clone(Native Method)

而且因为 Integer 没有实现 Cloneable,所以 clone() 方法会抛出 java.lang.CloneNotSupportedException。

于 2016-09-22T12:04:20.707 回答