我正在尝试使用泛型类型创建二叉树,我有一个我不明白的错误。我尝试了两种编码方式,第二种方法有效。我不明白为什么第一次失败。
我有以下常用代码:
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,那就好了。 (我通过创建一个额外的函数来编写代码来满足这一要求)但我不希望这样做。
谢谢
答案 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>
,而T
是String
。
通过将泛型参数作为T
传入,编译器可以检查value
的类型和节点的类型是否匹配。
答案 1 :(得分:1)
BT_Node可以使用T而无需再次参数化,删除其T参数。
否则你必须使用不同的Ts,这可能是他们的Comparable的不同扩展。
也没有BT_Node<T>
。