简体   繁体   English

如何在Java类层次结构中实现泛型类型安全的深度克隆?

[英]How to implement generic type-safe deep cloning in a Java class hierarchy?

I have a base class, say Base which specifies the abstract method deepCopy , and a myriad of subclasses, say A , B , C , ... Z . 我有一个基类,比如Base ,它指定了抽象方法deepCopy ,以及无数的子类,比如说ABC ,...... Z How can I define deepCopy so that its signature is public X deepCopy() for each class X ? 如何定义deepCopy ,使其签名为每个类X public X deepCopy()

Right, now, I have: 对,现在,我有:

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

Unfortunately, that means that if if I have an object from a subclass, say a of A , then I always have to perform an unchecked cast for a more specific deep copy: 不幸的是,这意味着,如果,如果我有从子类的对象,说aA ,然后我总是有一个更具体的深层副本执行未经检查的转换:

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

Is there a way, perhaps using generics, to avoid casting? 有没有办法,也许使用泛型,以避免施法? I want to guarantee that any deep copy returns an object of the same runtime class. 我想保证任何深层副本都返回同一运行时类的对象。

Edit: Let me extend my answer as covariant typing isn't enough. 编辑:让我扩展我的答案,因为协变打字是不够的。 Say, I then wanted to implement a method like: 说,然后我想实现一个方法,如:

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;
  }

How could I avoid the unchecked warning? 我怎么能避免未经检查的警告?

Java 5 supports covariant return types which means that you can implement your deepCopy() method in each subclass to return the specific sub-class instance; Java 5支持协变返回类型,这意味着您可以在每个子类中实现deepCopy()方法以返回特定的子类实例; eg 例如

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

  }
}

More on covariant return types here . 更多关于协变返回类型的信息

This is really not pretty, and I probably wouldn't do it myself, but: 这真的不太漂亮,我可能不会自己做,但是:

    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;
    }
}

Or.... 要么....

    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;
    }
}

How about... 怎么样...

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

Then... for example... (with errors, but good intentions; help!) 然后......例如......(有错误,但有好意;有帮助!)

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;
  }
} 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM