如何在泛型类中正确实现对 clone() 的调用 [Java]

我有一个通用接口,我必须创建一个类来实现它。起初我认为这会很好,将它放在文档中,接口需要一个实现克隆方法的类


genericClass<E extends Cloneable> implements genericInterface<E extends Cloneable>{

E data;


//code


public E get(){

return this.data.clone()

}

}

然而这在实践中不起作用


package securedatacontainer;


public class Demo {



    public static void main(String[] args) throws CloneNotSupportedException {


        String s = "user";

        A a = new A(5, s);

        A b = a.clone();

        System.out.println("a equals b: " +(a.equals(b)));

        System.out.println("a == b: " + (a == b));



        B<A> c = new B<>(a);

        System.out.println("a equals c.data: " +(a.equals(c.data)));

        System.out.println("a == c.data: " + (a == c.data));


        A k = c.get();

        System.out.println(k.value);


    }


}



class A implements Cloneable{

    int value;

    String name;



    public A(int x, String str ){

        this.value = x;

        this.name  = str;

    }


    @Override

    public A clone() throws CloneNotSupportedException {

    A temp = new A(this.value, this.name);

    return temp;

    }



    public boolean equals(A elem){

        return (this.name).equals(elem.name) && this.value==elem.value;

    }

}





class B <E extends Cloneable>{

    E data;


    public B(E elem){

        this.data=elem;

    }


    public E get() throws CloneNotSupportedException{

        return (E) this.data.clone();

    }



}

我明白了


Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - Erroneous sym type: java.lang.Cloneable.clone

    at securedatacontainer.B.get(Demo.java:60)

    at securedatacontainer.Demo.main(Demo.java:19)

因为这个项目应该是一个数据存储,我真的怀疑我的老师想要一些通用 E 元素的浅拷贝(注意这只是一个简单的克隆测试程序,而不是实际项目)。谁能告诉我为什么这不起作用或如何使它起作用?我不能对输入的 E 元素做任何假设,只是它有自己的 clone() 方法


蓝山帝景
浏览 423回答 1
1回答

天涯尽头无女友

因为该clone方法被标记为protected在Object类上,所以通常不能在任意对象上调用此方法。该clone()方法背后的想法是支持它的类将覆盖该方法,将其声明为公共的。这里唯一保留完整功能的真正解决方案是使用反射来访问方法并绕过访问修饰符。所以这是我的解决方案,public class B<E extends Cloneable> {&nbsp; &nbsp; E data;&nbsp; &nbsp; public B(E elem) {&nbsp; &nbsp; &nbsp; &nbsp; this.data = elem;&nbsp; &nbsp; }&nbsp; &nbsp; @SuppressWarnings("unchecked")&nbsp; &nbsp; public E get() {&nbsp; &nbsp; &nbsp; &nbsp; Method clone = null;&nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; clone = data.getClass().getMethod("clone");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Object[] args = new Object[0];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return (E) clone.invoke(data, args);&nbsp; &nbsp; &nbsp; &nbsp; } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | InvocationTargetException e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new RuntimeException(e);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}Clonable确定 Object 的受保护克隆实现的行为:如果类实现了Cloneable,则 Object 的 clone 方法返回对象的逐字段副本;否则它会抛出CloneNotSupportedException. 但是您在类A中实现克隆方法的方式不会调用Object's clone方法,因此这没有效果。@Overridepublic A clone() throws CloneNotSupportedException {&nbsp; &nbsp; A temp = new A(this.value, this.name);&nbsp; &nbsp; return temp;}&nbsp;如果您想使用该功能,则必须像这样实现它,public class A implements Cloneable {&nbsp; &nbsp; int value;&nbsp; &nbsp; String name;&nbsp; &nbsp; public A(int x, String str) {&nbsp; &nbsp; &nbsp; &nbsp; this.value = x;&nbsp; &nbsp; &nbsp; &nbsp; this.name = str;&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public A clone() throws CloneNotSupportedException {&nbsp; &nbsp; &nbsp; &nbsp; return (A) super.clone();&nbsp; &nbsp; }&nbsp; &nbsp; public boolean equals(A elem) {&nbsp; &nbsp; &nbsp; &nbsp; return (this.name).equals(elem.name) && this.value == elem.value;&nbsp; &nbsp; }}在这种情况下,如果您的类A没有实现,Cloneable那么java.lang.CloneNotSupportedException将被抛出。最后,public class B<E extends Cloneable>如果您尝试将未实现的内容Cloneable传递B给Demo类中的构造函数,则该声明会给您一个编译器错误。B<A> c = new B<>(doesNotImplCloneable);&nbsp; &nbsp;// Gives a compilation error.因此,如果您正在使用我在这里展示的对象的克隆方法,那么这extends/implements Cloneable就是要走的路。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java