解决此铸件行为的最简洁方法

时间:2012-07-22 14:40:48

标签: java generics inheritance types downcast

想象一下,我有一个列表,其中有50种不同类型的Node的某些子类,我希望它们是相同的类型,否则就会获得ClassException。我有一个接收此列表的方法以及一个持有和消除某种类型的节点

我想做这样的事情:

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节点),所以期待E.我想改变这个以接受任何类型的Node并进行转换。但后来发生这种情况:Why a List<type> absorbs not-type element in compilation and execution time?

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

2 个答案:

答案 0 :(得分:1)

假设特定类的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));
    }
}

答案 1 :(得分:0)

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

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