2009-09-03 9 views
2

私は抽象メソッドdeepCopyを指定する基本クラス、例えばBaseと、無数のサブクラス、例えばABC、... Zを持っています。どのようにしてdeepCopyを定義して、各クラスXの署名がpublic X deepCopy()になるのでしょうか?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

答えて

5

Java 5は共変リターン型をサポートしています。つまり、各サブクラスでdeepCopy()メソッドを実装して、特定のサブクラスインスタンスを返すことができます。例えば

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

    } 
} 

その他の共変戻り型の詳細here

+0

ありがとう!私はあなたが私の元の質問に答えたと思いますが、私の問題をかなり解決しませんでした。 :-) – namin

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これは、サブクラスが独自の型のオブジェクトを返さなければならないことを指定する唯一の方法です。 –

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; 
    } 
} 
関連する問題