由于clone
方法在Object
类中是受保护的,因此它不是public
。
唯一可以访问对象的clone()
方法的方式是知道它具有公共clone()
方法的编译时类型。
java.lang
包中,并且你没有调用this.clone()
而是anObject.clone()
,所以你的第二个观点也不适用。 - assylias以下是使克隆工作的最低要求:
public class SubObj implements Cloneable {
public Object clone() { return super.clone(); }
}
根据Java SE文档:
Object类本身不实现Cloneable接口,因此在一个类为Object的对象上调用clone方法将导致运行时抛出异常。
protected
字段只能从同一包内部访问,因此 Object
类的 clone()
方法只能从位于 java.lang
包中的任何类中访问。
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 extends Exception
抛出此异常表示调用 Object 类中的克隆方法来克隆对象,但该对象的类未实现 Cloneable 接口。重写克隆方法的应用程序也可以抛出此异常,以指示无法或不应克隆对象。
对象没有实现任何接口,为了使我的用户类正常工作,它必须实现 Cloneable
接口。
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
[编辑]
最初的问题是关于为什么该方法以这种方式可见。这是因为它只对java.lang包内的方法可访问。它不是为了让程序员能够克隆一个Object
。如果您不希望自己的对象被克隆,抛出CloneNotSupportedException
正是您想要做的。
void method() {
Object obj=new Object(); //Object is a parent class, it's not inherit from any other class...
obj.clone(); // compile time error
}
在API级别中,Object类的clone()方法已被修改为受保护的访问修饰符。因此,我们无法在没有继承的情况下随意访问它。因此,在调用对象类的clone()方法之前,您需要实现Cloneable接口。然后代码将在运行时正确运行。否则,它将在运行时生成CloneNotSupportedException。
/*Subclass is my implementing class */
public class SubClass implements Cloneable {
@Override
public SubClass clone() throws CloneNotSupportedException {
return (SubClass) super.clone();
}
}
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 for:The method clone() from the type Object is not visible
people p2 = (people)p1.clone();
// Ok
people p3 = (people)p1.myclone();
test()
不属于子类。
所以即使通过人物对象p1
调用clone()
,它也不是people
对象的位置。
myclone()
正是人物对象的位置。