Java 修复此行为的最干净方法

Java 修复此行为的最干净方法,java,generics,inheritance,types,downcast,Java,Generics,Inheritance,Types,Downcast,假设我有一个包含50个不同类型的节点子类的列表,我希望这些子类是相同的类型,否则会得到一个类异常。我有一个方法来接收这个列表和一个节点,它持有并导出某个类型 我想这样做: public <E extends Node> receive(List<Node> list, Node<E extends Node> node){ for (Node element : list ){ node.addElement((E) element)

假设我有一个包含50个不同类型的节点子类的列表,我希望这些子类是相同的类型,否则会得到一个类异常。我有一个方法来接收这个列表和一个节点,它持有并导出某个类型

我想这样做:

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 ){
         node.addElement(element.autoDowncastToSubClassOf("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));
    }
}
公共接收(列表、节点){
用于(节点元素:列表){
node.addElement((E)element);//如果在运行时放置了错误的node no CastException,则键入erasure
}
}
但要避免这样做:

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);
    }
}
公共接收(列表、节点){
用于(节点元素:列表){
if(子节点1的元素实例)node.addElement((子节点1)元素);
else if(子节点2的元素实例)node.addElement((子节点2)元素);
//(...)
else if(子节点50的元素实例)node.addElement((子节点50)元素);
}
}
如果我不能转换为generic,那么做这样的事情会很好:

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 ){
         node.addElement(element.autoDowncastToSubClassOf("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));
    }
}
公共接收(列表、节点){
用于(节点元素:列表){
node.addElement(element.autoDowncastToSubClassOf(“节点”);
}
}
所有这些选项都考虑了node.addElement(E node),所以期望的是E。我考虑过将其更改为接受任何类型的节点并进行转换。但后来发生了这样的事情:


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

由于没有答案,经过大量研究并以不同方式聚焦主题后,这里给出了线索,我指出了预期的解决方案:


假设一个特定的节点类始终将其自己的节点类作为元素

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

class Node<E> {
    public void addSubElement(E node) { ... }
}
类节点{
公共void addSubElement(E节点){…}
}
然后您的节点类都是这样的:

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 ){
         node.addElement(element.autoDowncastToSubClassOf("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扩展节点
然后您可以这样编写您的方法:

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 ){
         node.addElement(element.autoDowncastToSubClassOf("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));
    }
}
公共接收(列表元素:列表){
node.addElement(node.getClass().cast(element));
}
}

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