4

我正在尝试使用泛型类型创建二叉树,但出现了一个我不明白的错误。我尝试了两种编码方式,第二种有效。我不明白为什么第一个失败了。

我有以下通用代码:

public class MyTreea <T extends Comparable<T>> 
{     
   class BT_Node<T extends Comparable<T>>
           {
            T           value;
            BT_Node<T>  left;
            BT_Node<T>  right;

            BT_Node(T node_value) 
                  { 
                    this.value   = node_value ;
                    left         = null;
                    right        = null;
                  }
           }           

区别在于插入过程:这有效:

 private BT_Node<T> insert(BT_Node<T> node, BT_Node<T> newNode) {
      if ((node.value).compareTo(newNode.value) == 0) { . . . }

但这失败了

  private BT_Node insert(BT_Node node, T value) {
        if (value.compareTo(node.value) == 0) { . .  

和:

MyTreea.java:28: error: method compareTo in interface Comparable<T#2> cannot be applied to given types;
            if (value.compareTo(node.value) == 0)
required: T#1
found: Comparable
reason: actual argument Comparable cannot be converted to T#1 by method invocation conversion
where T#1,T#2 are type-variables:
T#1 extends Comparable<T#1> declared in class MyTreea
T#2 extends Object declared in interface Comparable

显然,如果我用两个节点参数调用 BT_insert 就可以了。(我通过创建一个额外的函数来编写代码来满足这一点)但我不希望这样。

谢谢

4

2 回答 2

3

您应该能够使用具有以下签名的第二个示例:

private BT_Node<T> insert(BT_Node<T> node, T value) 

您给出的示例使用“原始类型”(即没有泛型参数的泛型类),这通常总是一个坏主意,并且可以说只是为了与 Java 1.4 向后兼容而存在。 BT_Node是一个泛型类,所以你应该总是给它一个泛型参数。

如果您没有这样做,这大致相当于传入BT_Node<?>,因为 Node 的泛型参数可以有任何值。所以编译器不能保证value你传入的类型是正确的——例如,第一个参数可能是 a BT_Node<Int>,而Tis String

通过传入泛型参数 as T,编译器可以检查 的类型value和节点的类型是否匹配。

于 2013-04-25T08:37:01.377 回答
1

BT_Node 可以使用 T 而无需再次对其进行参数化,删除其 T 参数。

否则,您必须使用不同的 T,这可能是其 Comparable 的不同扩展。也没有BT_Node<T>

于 2013-04-25T08:35:37.310 回答