Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在多态树中使用Java泛型类型参数_Java_Dynamic_Types_Bounded Types - Fatal编程技术网

如何在多态树中使用Java泛型类型参数

如何在多态树中使用Java泛型类型参数,java,dynamic,types,bounded-types,Java,Dynamic,Types,Bounded Types,我有一个看起来像树的大数据结构。我有一个根类TreeElement,它实现所有树行为、链接、取消链接、导航等。树中的实际节点将是TreeElement类的专用子类。给定的父节点将具有多种类型的子节点。下面是一个示例树: NodeTypeA + NodeTypeB + NodeTypeC + NodeTypeC + NodeTypeB + NodeTypeC + NodeTypeD + NodeTypeE 如您所见,NodeTypeA具有类型B和D的子级(可能还有其他子级),而N

我有一个看起来像树的大数据结构。我有一个根类TreeElement,它实现所有树行为、链接、取消链接、导航等。树中的实际节点将是TreeElement类的专用子类。给定的父节点将具有多种类型的子节点。下面是一个示例树:

NodeTypeA
+ NodeTypeB
  + NodeTypeC
  + NodeTypeC
+ NodeTypeB
  + NodeTypeC
+ NodeTypeD
  + NodeTypeE
如您所见,NodeTypeA具有类型B和D的子级(可能还有其他子级),而NodeTypeB具有类型C的子级(可能还有其他子级)。NodeTypeD具有E类型的子级(可能还有其他类型)。所有这些都是TreeElement的子类。专门的子类对允许他们生的孩子的种类有一些了解

基类型TreeElement有一个方法

Vector getChildren(String kind, Class nodeType);
这将返回一个向量,该向量中填充了所有标记为“种类”和“类”的子级,这些子级是由传入的类指定的。返回的向量将始终包含传入的类的元素。问题是我正在尝试实现正确的类型安全性,我不清楚如何使用java的动态类型功能来实现这一点

在NodeTypeA类中,我想要一个这样的方法来获取NodeTypeB的子级:

Vector<NodeTypeB> getSpecialChildren() {
    Vector<NodeTypeB> vb = getChildren("special", NodeTypeB.class);
    return vb;
}
向量getSpecialChildren(){ 向量vb=getChildren(“特殊”,NodeTypeB.class); 返回vb; } 当我写上述内容时,我在Eclipse中得到一个警告,即需要类型转换。因此,我可以添加类型转换:

Vector<NodeTypeB> getSpecialChildren() {
    Vector<NodeTypeB> vb = (Vector<NodeTypeB>) getChildren("special", NodeTypeB.class);
    return vb;
}
向量getSpecialChildren(){ Vector vb=(Vector)getChildren(“特殊”,NodeTypeB.class); 返回vb; } 但是,我还有Eclipse的特性“删除不必要的强制转换”,这个特性删除了这个强制转换。这似乎有点奇怪,Eclipse认为它是不必要的,但如果它不存在就会发出警告。但这只是一种烦恼


我真正想做的是使用Java的动态类型机制(这是“有界类型参数”吗?)。我根本不知道如何在TreeeElement类中声明getChildren方法来实现这种具有完全类型安全性的机制——我假设消除了类参数。任何帮助都会被理解。

你应该考虑做嵌套集合树或邻接树的实现。我为嵌套集树创建了一些类,这些类使用了非常有用的泛型,并且很容易重新调整用途

它的核心看起来像:

public class NestedSetTree<? extends NestedSetTree<T>> 

公共类NestedSetTree修复getChildren声明的方法是:

public <T extends TreeElement> Vector<T> getChildren(String string, Class<T> nodeType)
公共向量getChildren(字符串、类节点类型)
这将使编译器在您使用时不必理会类型警告


该方法的实现中仍然会有一些警告,因为泛型是一种编译时功能,并且您提供了一个运行时类型参数,但是这些警告至少会在该方法中被隔离。

我不认为这是可能的。Java的类型系统不够强大,无法在所描述的结构中提供所需的保证。坦白地说,如果我是你,我会放弃将它们放入一般的“树”类型的尝试,并用一个普通的类结构来实现这一点,
NodeTypeA
只是一个旧类,没有扩展任何内容,它有一个
List
和一个
List
字段,如果不修复它,就无法实现编译器保证的类型安全。@aff-这正是我要问的问题:如何准确地修复getChildren@Louis-也许你是对的,但我仍然希望。。。。实际上,实际情况比我在这里介绍的要复杂得多:我必须利用标准的行走和操纵树的机制。这棵树实际上是由包裹另一棵树的元素的对象组成的,我无法控制它。我不想让这个问题因为这些而陷入困境。只是想弄清楚是否有方法声明getChildren来获取调用方指定的类型。泛型是java中的编译时特性。采用运行时类型参数作为参数的方法永远不会由编译器通过泛型系统100%保证安全。请参阅我的答案,了解如何声明该方法,以使警告在该方法内部而不是在您使用它的任何地方被隔离。不清楚如果存在不同类型的子级,这可能会如何工作。例如,此方法执行:
http://docs.oracle.com/javaee/6/api/javax/persistence/EntityManager.html#createQuery(java.lang.String,java.lang.Class)
?实际的实现是一个运行时类型操作,它不是编译时安全的,但是我们信任它,并通过以这种方式构造签名来告诉编译器信任它。好的,这基本上起作用了!它在我需要研究的代码库中导致了5个错误。其中一个错误是,当方法需要返回接口集合时,具体类实现了接口,但我得到了一个错误。既然这是一个不同的问题,我现在就不想把这个问题/答案复杂化,看看我能不能在其他地方找到答案。就这样。我不得不对接口向量和超类向量进行一些强制转换,但这消除了代码中约80个类型强制转换警告。