泛型返回类型不起作用

时间:2012-01-22 05:41:48

标签: java generics visitor-pattern

我正在经历榜样。

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.为什么会这样,以及如何解决问题。

4 个答案:

答案 0 :(得分:3)

在您的情况下,有两个问题:

  1. T extends Integer不完全有效,因为Integer无法扩展,即它是final类。因此,您可以安全地将类声明更改为

    class Sum implements Visitor<Integer> { ...
    
  2. 其次,T value()方法不是接口的一部分,因此不需要(不应该)类型为T。您可以使用public int value()public Integer value()安全地替换它。

  3. 因此,生成的代码如下所示:

    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, FloatLong

答案 3 :(得分:1)

您可以在类intValue上使用Integer方法(实际上继承自Number),即

sum += element.intValue();

你不能只使用sum += element的原因是编译器不知道具体的类T是什么,所以它不能自动装箱。 T 可能Integer,但您已将T声明为T extends Integer,因此编译器不知道子类{{1}实际上是。

现在,在你的情况下它会变得有趣,因为T是一个最终的类。您可以争辩说编译器应该能够确定Integer始终为T。它显然不会这样做。

也许这是你不想使用泛型的情况:永远不会有Integer的子类,为什么不完全摆脱泛型声明呢?

Integer

这应该可以正常工作。