【问题标题】:Cleanest way to fix this castings behavior解决这种铸件行为的最干净的方法
【发布时间】:2012-07-22 14:40:48
【问题描述】:

想象一下,我有一个包含 50 种不同类型的 Node 子类的列表,我希望它们是相同的类型,否则会得到 ClassException。我有一个接收这个列表的方法和一个持有和 expeting 某种类型的节点

我想做这样的事情:

public <E extends Node> receive(List<Node> list, Node<E extends Node> node){
    for (Node element : list ){
         node.addElement((E) element); //Type erasure, if you put wrong node no CastException in Runtime 
    }
}

但避免这样做:

public <E extends Node> receive(List<Node> list, Node<E extends Node> node){
    for (Node element : list ){
         if      (element instanceof SubNode1) node.addElement((Subnode1) element); 
         else if (element instanceof SubNode2) node.addElement((Subnode2) element);
         //(...)
         else if (element instanceof SubNode50) node.addElement((Subnode50) element);
    }
}

如果我不能转换为泛型,那么做这样的事情会很棒:

public <E extends Node> receive(List<Node> list, Node<E extends Node> node){
    for (Node element : list ){
         node.addElement(element.autoDowncastToSubClassOf("Node"));
    }
}

所有这些选项都考虑了 node.addElement(E node),所以期待 E。我想改变它以接受任何类型的节点并进行演员表。但后来发生了这样的事情:Why a List<type> absorbs not-type element in compilation and execution time?

我应该放弃第二种方法吗?

【问题讨论】:

  • 为什么在将节点添加到列表时感觉必须强制转换?强制转换不会添加任何内容,因为它不会更改添加到树中的基础对象的类型。它可能会改变持有对象的参数的类型,但底层对象仍然没有改变,一旦添加到列表树中,转换就好像它从未发生过,因为参数消失了。
  • 我没有将节点添加到列表中。我有一个节点列表,因为有一个外部代码,但是这个列表预计将填充一个子节点类型 E,如果不是这样,它应该很快抛出一些异常
  • 但是强制转换并不能解决这个问题。
  • instanceof 示例(第二个)按预期工作。但我需要一些动态的机制来实现它
  • 你是在告诉我们 yoiu 有 50 个重载的getElement 方法吗?如果是的话,除了反射没有什么可以为你解决的。

标签: java generics inheritance types downcast


【解决方案1】:

假设某个特定的Node类总是以自己的Node类作为元素,

假设你有一个类或接口,例如:

class Node<E> {
    public void addSubElement(E node) { ... }
}

然后你的 Node 类都是这样的:

class Subnode1 extends Node<Subnode1>

那么你也许可以这样写你的方法:

public <E extends Node<E>> receive(List<Node<?>> list, E node){
    for (Node<?> element : list) {
         node.addElement(node.getClass().cast(element));
    }
}

【讨论】:

    【解决方案2】:

    由于对此没有答案,并且经过大量研究并以不同方式关注该主题后,此处给出了线索​​,因此我指出了预期的解决方案:

    How can I downcast to class' type E or at least make it in a safe way without warnings?

    【讨论】:

      猜你喜欢
      • 2023-04-03
      • 2016-11-26
      • 2021-07-11
      • 1970-01-01
      • 2021-03-20
      • 1970-01-01
      • 1970-01-01
      • 2011-03-01
      • 2010-09-18
      相关资源
      最近更新 更多