Java - 泛型类型

时间:2013-04-25 08:33:03

标签: java

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

我有以下常用代码:

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,那就好了。 (我通过创建一个额外的函数来编写代码来满足这一要求)但我不希望这样做。

谢谢

2 个答案:

答案 0 :(得分:3)

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

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

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

如果你没有,这大致相当于传入BT_Node<?>,因为Node可以为其泛型参数赋值。因此,编译器无法保证您传入的value具有正确的类型 - 例如,第一个参数可以是BT_Node<Int>,而TString

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

答案 1 :(得分:1)

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

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