亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在泛型類中正確實現對 clone() 的調用 [Java]

如何在泛型類中正確實現對 clone() 的調用 [Java]

藍山帝景 2022-01-12 16:08:45
我有一個通用接口,我必須創建一個類來實現它。起初我認為這會很好,將它放在文檔中,接口需要一個實現克隆方法的類genericClass<E extends Cloneable> implements genericInterface<E extends Cloneable>{E data;//codepublic 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() 方法
查看完整描述

1 回答

?
天涯盡頭無女友

TA貢獻1831條經驗 獲得超9個贊

因為該clone方法被標記為protected在Object類上,所以通常不能在任意對象上調用此方法。該clone()方法背后的想法是支持它的類將覆蓋該方法,將其聲明為公共的。


這里唯一保留完整功能的真正解決方案是使用反射來訪問方法并繞過訪問修飾符。


所以這是我的解決方案,


public class B<E extends Cloneable> {

    E data;


    public B(E elem) {

        this.data = elem;

    }


    @SuppressWarnings("unchecked")

    public E get() {

        Method clone = null;

        try {

            clone = data.getClass().getMethod("clone");

            Object[] args = new Object[0];

            return (E) clone.invoke(data, args);

        } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException

                | InvocationTargetException e) {

            throw new RuntimeException(e);

        }


    }

}

Clonable確定 Object 的受保護克隆實現的行為:如果類實現了Cloneable,則 Object 的 clone 方法返回對象的逐字段副本;否則它會拋出CloneNotSupportedException. 但是您在類A中實現克隆方法的方式不會調用Object's clone方法,因此這沒有效果。


@Override

public A clone() throws CloneNotSupportedException {

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

    return temp;

如果您想使用該功能,則必須像這樣實現它,


public 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 {

        return (A) super.clone();

    }


    public boolean equals(A elem) {

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

    }

}

在這種情況下,如果您的類A沒有實現,Cloneable那么java.lang.CloneNotSupportedException將被拋出。


最后,public class B<E extends Cloneable>如果您嘗試將未實現的內容Cloneable傳遞B給Demo類中的構造函數,則該聲明會給您一個編譯器錯誤。


B<A> c = new B<>(doesNotImplCloneable);   // Gives a compilation error.

因此,如果您正在使用我在這里展示的對象的克隆方法,那么這extends/implements Cloneable就是要走的路。


查看完整回答
反對 回復 2022-01-12
  • 1 回答
  • 0 關注
  • 396 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號