我正在经历榜样。
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;
}
}
返回语句T value()返回sum表示类型不匹配:无法从int转换为T.为什么会这样,以及如何解决问题。
答案 0 :(得分:3)
在您的情况下,有两个问题:
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;
}
}
答案 1 :(得分:1)
这是因为int
是Java中的基本类型,而Integer
是一个类。问题是您无法直接将int
分配给Integer
。解决方案可能是将return sum;
更改为return (T) sum;
。
答案 2 :(得分:1)
在泛型实现中,始终使用Wrapper
类而不是primitive
数据类型。
例如对于int
,您应该将Integer
同样用于double,float,long等。可用的包装类分别为Double, Float
和Long
。
答案 3 :(得分:1)
您可以在类intValue
上使用Integer
方法(实际上继承自Number
),即
sum += element.intValue();
你不能只使用sum += element
的原因是编译器不知道具体的类T
是什么,所以它不能自动装箱。 T
可能为Integer
,但您已将T
声明为T extends Integer
,因此编译器不知道子类{{1}实际上是。
现在,在你的情况下它会变得有趣,因为T
是一个最终的类。您可以争辩说编译器应该能够确定Integer
始终为T
。它显然不会这样做。
也许这是你不想使用泛型的情况:永远不会有Integer
的子类,为什么不完全摆脱泛型声明呢?
Integer
这应该可以正常工作。