【问题标题】:How to implement generic type-safe deep cloning in a Java class hierarchy?如何在 Java 类层次结构中实现泛型类型安全的深度克隆?
【发布时间】:2009-09-03 21:53:37
【问题描述】:

我有一个基类,比如Base,它指定了抽象方法deepCopy,还有无数的子类,比如ABC、...Z。如何定义deepCopy,使其签名为public X deepCopy(),每个类X

好的,现在,我有:

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

如何避免未经检查的警告?

【问题讨论】:

标签: java generics casting unchecked


【解决方案1】:

Java 5 支持协变返回类型,这意味着您可以在每个子类中实现 deepCopy() 方法以返回特定的子类实例;例如

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

  }
}

更多关于协变返回类型here

【讨论】:

  • 谢谢!我猜你回答了我最初的问题,但并没有完全解决我的问题。 :-)
【解决方案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;
    }
}

【讨论】:

  • +1,这是指定子类必须返回自己类型的对象的唯一方法。
【解决方案3】:

怎么样...

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-14
    • 2013-03-20
    • 2017-02-10
    • 1970-01-01
    相关资源
    最近更新 更多