当我尝试克隆泛型Object时,我得到编译时错误。为什么呢?
Object obj=new Object();
obj.clone(); // Here compile time error "The method clone() from the type Object is not visible"
每个类扩展Object类,克隆方法在Object类中受到保护。
protected
方法可以在同一个包中访问,也可以在subclasses
中访问,所有类都是java.lang.Object
的子类。
答案 0 :(得分:9)
因为clone
类中Object
受保护。这不是public
。
访问对象的clone()
方法的唯一方法是知道它具有一个具有公共clone()
方法的编译时类型。
答案 1 :(得分:3)
根据Java SE docs:
类Object本身并不实现Cloneable接口,所以 在类为Object的对象上调用clone方法 导致在运行时抛出异常。
答案 2 :(得分:1)
这将是克隆工作的最低要求:
public class SubObj implements Cloneable {
public Object clone() { return super.clone(); }
}
答案 3 :(得分:1)
protected
个字段只能从同一个包中访问,因此clone()
类的Object
方法只能从位于java.lang
包中的任何类访问
答案 4 :(得分:0)
您必须明确地实现Cloneable接口。 见this thread给出解释。
答案 5 :(得分:0)
如果您使用Groovy以便绕过java编译错误,那么您将得到:
Exception in thread "main" java.lang.CloneNotSupportedException: java.lang.Object
at java.lang.Object.clone(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:86)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:230)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:912)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:756)
at org.codehaus.groovy.runtime.InvokerHelper.invokePojoMethod(InvokerHelper.java:766)
at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:754)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:170)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethod0(ScriptBytecodeAdapter.java:198)
at regexTests.main(regexTests.groovy:19)
ERROR: JDWP Unable to get JNI 1.2 environment, jvm->GetEnv() return code = -2
JDWP exit error AGENT_ERROR_NO_JNI_ENV(183): [../../../src/share/back/util.c:820]
如果您阅读了克隆API(我将链接它),它表示如果未实现接口,则调用* .clone()将抛出CloneNotSupportedException
。
链接到java.lang.Object
的克隆API
http://docs.oracle.com/javase/6/docs/api/java/lang/Object.html#clone%28%29
[编辑]
Original Question™询问为什么这种方法以其可见方式可见。这是因为它只能访问java.lang包中的方法。程序员不能克隆Object
。如果您不希望克隆自己的OWN对象,则抛出CloneNotSupportedException
正是您想要做的。
答案 6 :(得分:0)
void method() {
Object obj=new Object(); //Object is a parent class, it's not inherit from any other class...
obj.clone(); // compile time error
}
我们无法从不同的包访问受保护的“Has A”关系方法,因为您的Class包是(com.xxx.yyy)而Object类包是(java.lang)这两个类是不同的封装
受保护的方法可以在同一个包中以及通过子类(IS A关系)访问
答案 7 :(得分:0)
我试过这段代码:
public final class User {
private String name;
private boolean isActive;
private String userId;
private Address address;
// can be constructed using this constructor ONLY !
public User(String name, boolean isActive, String userId, Address address) {
this.name = name;
this.isActive = isActive;
this.userId = userId;
this.address = address;
}
public String getName() {
return name;
}
public boolean isActive() {
return isActive;
}
public String getUserId() {
return userId;
}
public Address getAddress() {
return address;
}
protected Object cloneMe() throws CloneNotSupportedException {
return super.clone(); // throws CloneNotSupportedException
}
}
public class CloneNotSupportedException 扩展异常
抛出以指示Object类中的clone方法 调用克隆一个对象,但该对象的类没有 实现Cloneable接口。覆盖的应用程序 clone方法也可以抛出此异常来指示一个对象 不能或不应该克隆。
Object没有实现任何接口,为了使我的User类工作,它必须实现Cloneable
答案 8 :(得分:0)
对象类clone()方法已在API级别由受保护的访问修饰符进行了修改。因此,如果没有继承,我们将无法在任何地方访问它。因此,在调用对象类clone()方法之前,您需要实现Cloneable接口。然后,代码将在运行时正确运行。否则,它将在运行时生成CloneNotSupportedException。
/*Subclass is my implementing class */
public class SubClass implements Cloneable {
@Override
public SubClass clone() throws CloneNotSupportedException {
return (SubClass) super.clone();
}
}
答案 9 :(得分:0)
import java.util.Scanner;
import java.util.jar.Attributes.Name;
import java.util.Arrays;
public class Main{
public class man{
protected void name() {
System.out.println("hei");
}
}
public class people extends man{
public int age;
public int getAge() {
name();
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "people [age=" + age + "]";
}
public Object myclone() throws CloneNotSupportedException {
return this.clone();
}
}
public void test() throws CloneNotSupportedException {
people p1 = new people();
p1.setAge(10);
System.out.println(p1);
// NG:
people p2 = (people)p1.clone();
// Ok
people p3 = (people)p1.myclone();
p1.setAge(10);
System.out.println(p1);
System.out.println(p2);
}
public static void main(String args[]) throws CloneNotSupportedException{
new Main().test();
}
}
请参阅NG代码和ok代码。
// NG for:The method clone() from the type Object is not visible
people p2 = (people)p1.clone();
// Ok
people p3 = (people)p1.myclone();
为什么?
原因test()
不属于子类。
因此,即使有人对象clone()
调用p1
,也不是peopel
对象的位置。
myclone()
正是人们所反对的地方。