我正在尝试克隆一个 Integer 类的对象,它确实实现了可克隆接口。
Integer a = new Integer(4);
Integer b = a.clone();
我知道有解决方法,但我必须像这样实现它。为什么我收到此错误=
clone()
已保护访问java.lang.Object
为什么会这样说?克隆方法不是可克隆接口的公共抽象方法吗,和对象有什么关系。提前致谢 :-)
java.lang.Integer
s 是不可变的。没有理由克隆一个。如果您想浪费内存,请尝试Integer.valueOf(myInteger.intValue())
.
当然,其中的所有方法Object
都是继承的。然而,该clone
方法是protected
,因此只能从子类中访问。
protected 修饰符指定该成员只能在其自己的包中访问(与 package-private 一样),此外,它的类在另一个包中的子类也可以访问。
您可以在大多数其他情况下调用的原因是子类通过使用访问修饰符clone()
覆盖它来“打开它” 。public
出现错误是因为clone
java.lang.Object 的方法不公开可见。
正如 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 一样(因为它是不可变的)
首先,当您不希望其他人更改您的副本时,我需要通过克隆获得副本。现在 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.
可能很难相信,但您的错误是正确的:clone() has protected access in java.lang.Object
是的,因为 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());
}
您可以使用反射来调用克隆方法,而无需在对象中覆盖它。
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。