2009-09-03 63 views
2

我有一個基類,說Base,它指定的抽象方法deepCopy,以及無數的子類,說AB,C,。我如何定義deepCopy,使其簽名爲public X deepCopy(),每個類X如何在Java類層次結構中實現泛型類型安全的深度克隆?

權,現在,我有:

abstract class Base { 
    public abstract Base deepCopy(); 
} 

不幸的是,這意味着,如果,如果我有一個子類的對象,說aA的,然後我總是有一個更執行未經檢查的投特定的深拷貝:

A aCopy = (A) a.deepCopy(); 

有沒有一種方法,也許使用泛型,以避免鑄造?我想保證任何深層副本都會返回相同運行時類的對象。

編輯:讓我擴展我的答案,因爲協變鍵入是不夠的。說,然後我想實施一種方法,如:

static <N extends Base> List<N> copyNodes(List<N> nodes) { 
    List<N> list = Lists.newArrayList(); 
    for (N node : nodes) { 
     @SuppressWarnings("unchecked") 
     N copy = (N) node.deepCopy(); 
     list.add(copy); 
    } 
    return list; 
    } 

我怎樣才能避免未經檢查的警告?

+0

有幾個公用事業公司會爲你做這件事...... http://www.genericdeepcopy.com/和http://code.google.com/p/cloning/。 – Aaron 2011-12-25 17:03:23

回答

5

Java 5支持協變返回類型,這意味着您可以在每個子類中實現您的deepCopy()方法以返回特定的子類實例;例如

public class Z extends Base { 
    @Override 
    public Z deepCopy() { 

    } 
} 

有關協變返回類型的更多信息here

+0

謝謝!我想你回答了我原來的問題,但並沒有完全解決我的問題。 :-) – namin 2009-09-03 22:24:28

2

這實在是不漂亮,我可能不會做我自己,而是:

public abstract class Base<T extends Base<T>> { 
    public abstract T deepCopy(); 
} 
public class Extender extends Base<Extender> { 

    @Override 
    public Extender deepCopy() { 
     // TODO Auto-generated method stub 
     return null; 
    } 
} 

或者....

public abstract class Base<T extends Base<T>> { 
    public abstract T deepCopy(); 
} 
public class Extender<T extends Base<T>> extends Base<T> { 

    @Override 
    public T deepCopy() { 
     // TODO Auto-generated method stub 
     return null; 
    } 
} 
+0

+1,這是指定子類必須返回自己類型的對象的唯一方法。 – 2009-09-08 11:27:57

1

......怎麼

public interface DeeplyCloneable <T extends Cloneable> { 
    public T deepClone(); 
} 

然後...例如...(有錯誤,但是好意;幫助!)

public class DeeplyClonableHashTable 

     <T1 extends DeeplyCloneable<?>,T2 extends DeeplyCloneable<?>> 
extends Hashtable<T1,T2> 
implements DeeplyCloneable<Hashtable<T1,T2>>{ 

@Override 
public Hashtable<T1, T2> deepClone() { 
    Object o = super.clone(); 
    if ((o == null) || (! (o instanceof DeeplyClonableHashTable<?,?>))) 
    { 
    throw new DeepCloneException(
     "Object instance does not support deepCloneing."); 
    } 

    @SuppressWarnings("unchecked") 
    DeeplyClonableHashTable<T1,T2> copy = (DeeplyClonableHashTable<T1,T2>)o; 
    Set<T1> keys = copy.keySet(); 

    for (T1 key: keys){ 
    T2 value = this.get(key); 
    T1 keyCopy = key.deepClone(); // this line is in error 
    T2 valueCopy = value.deepClone(); // this line is in error 
    copy.put(keyCopy, valueCopy); 
    } 
    return copy; 
    } 
} 
相關問題