2

当我尝试克隆一个通用对象时,我得到编译时错误。为什么?

    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.

4

10 回答 10

9

因为在类clone受到保护。Object不是public

访问对象方法的唯一clone()方法是知道它有一个具有公共clone()方法的编译时类型。

于 2012-07-05T12:57:38.187 回答
3

根据Java SE 文档

Object 类本身并没有实现接口 Cloneable,因此在类为 Object 的对象上调用 clone 方法将导致在运行时抛出异常。

于 2012-07-05T12:59:41.467 回答
3

这将是让克隆工作的最低要求:

public class SubObj implements Cloneable {
  public Object clone() { return super.clone(); }
}
于 2012-07-05T13:01:25.157 回答
1

protected字段只能从同一个包内访问,因此类clone()的方法Object只能从位于java.lang包中的任何类访问。

于 2012-07-05T13:01:42.767 回答
0

您必须明确实现 Cloneable 接口。看到这个给出解释的线程。

于 2012-07-05T12:58:26.447 回答
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 http://docs.oracle.com/javase/6/docs/api/java/lang/Object.html#clone%28%29的克隆 API

[编辑] The Original Question™ 询问为什么这种方法以它的方式可见。这是因为它只能被 java.lang 包中的方法访问。它不是为了让程序员能够克隆Object. CloneNotSupportedException如果您不想克隆您的 OWN 对象,则 抛出 a正是您想要做的。

于 2012-07-05T13:08:22.297 回答
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 关系)

于 2014-08-12T07:00:21.087 回答
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
    }
}

公共类 CloneNotSupportedException 扩展异常

抛出表示调用了Object类中的clone方法克隆了一个对象,但是该对象的类没有实现Cloneable接口。覆盖 clone 方法的应用程序也可以抛出此异常,以指示无法或不应克隆对象。

对象没有实现任何接口,为了让我的用户类工作它必须实现Cloneable

于 2016-02-17T14:00:43.367 回答
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();
    }
}
于 2019-12-08T02:19:25.450 回答
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()正是人们反对的地方。

于 2020-08-29T15:19:52.280 回答