我正在学习这个例子。
public interface Visitor<T> {
public void visit(T e);
}
class Sum<T extends Integer> implements Visitor<T> {
private int sum = 0;
@Override
public void visit(T element) {
sum += element;
}
public T value() {
return sum;
}
}
return语句T value()return sum给出了一个错误,指出类型不匹配:无法从int转换为T。为什么会这样,以及如何解决问题。
在您的案例中有两个问题:
-
T extends Integer
并不完全有效,因为Integer
不能扩展,即它是final
类。因此,您可以安全地将类声明更改为class Sum implements Visitor<Integer> { ...
-
其次,
T value()
方法不是接口的一部分,因此不需要(不应该)是T
类型。您可以安全地将其替换为public int value()
或public Integer value()
。
因此,生成的代码将如下所示:
class Sum implements Visitor<Integer> {
private int sum = 0;
@Override
public void visit(Integer element) {
sum += element.intValue();
}
public int value() {
return sum;
}
}
在泛型实现中,始终使用Wrapper
类而不是primitive
数据类型。例如,对于int
,您应该同样使用Integer
来表示double、float、long等。可用的包装类分别为Double, Float
和Long
。
int
是Java中的基元类型,而Integer
是一个类。问题是不能将int
直接分配给Integer
。解决方案可以是将CCD_ 18改变为CCD_。
您可以在类Integer
(实际上继承自Number
)上使用intValue
方法,即
sum += element.intValue();
不能只使用sum += element
的原因是编译器不知道T
是什么具体类,所以它不能自动装箱。T
可以是Integer
,但您已经将T
声明为T extends Integer
,所以编译器不知道T
实际上是什么子类。
现在,在您的案例中,它变得有点有趣,因为Integer
是最后一个类。您可能会争辩说编译器应该能够计算出T
将始终是Integer
。它显然不能做到这一点。
也许这是一种你不想使用泛型的情况:Integer
永远不可能有一个子类,那么为什么不完全去掉泛型声明呢?
class Sum implements Visitor<Integer> {
public void visit(Integer i) {
sum += i;
}
}
这应该很好用。