2012-01-22 163 views
2

我正在通过示例。泛型返回类型不起作用

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值()返回的总和给出错误,指出类型不匹配:不能从int到T.转换为什么它是如此,如何来解决这个问题。

+0

不应该是'私人T sum = 0;'? –

+0

并非所有的猫都是狮子,你知道......;-)如果T sum = 0,则为 – Cameron

+0

;我无法将我的元素添加到总和中。我的意思是sum + = element;在第二种方法中将给出错误。对于参数类型T,运算符+ =未定义。 – Curious

回答

3

你的情况有两个问题:

  1. T extends Integer是不完全有效的,因为Integer不能扩展,即它是一个final类。因此您可以在类声明安全更改为

    class Sum implements Visitor<Integer> { ... 
    
  2. 其次,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; 
    } 
} 
+0

非常感谢。 – Curious

1

这是因为int是Java中的原始类型,而Integer是一类。问题是你不能直接将int分配给Integer。解决办法可能是将return sum;更改为return (T) sum;

+0

返回新的T(sum)也不返回新的T(sum)正在工作中不能实例化类型T的错误。 – Curious

+0

public int value(){ \t \t return sum; \t}非常感谢你。但是想知道T(sum)的意思。 – Curious

+0

考虑到'Integer'有一个构造函数作为'Integer(int)',我尝试用'new T(sum)'来表示'用int创建一个新的T实例'(假设'T'为'Integer'你更清楚的印象)。但后来我发现'Integer'是一个不能扩展(或派生)的最终类。我可以在这里知道你的'T'和'Integer'究竟是什么?你是指Java中默认的'Integer'? – grapeot

1

在泛型实现中,始终使用Wrapper类而不是primitive数据类型。 例如对于int,您应该同样使用Integer进行double,float,long等。有可用的包装类别分别为Double, FloatLong

1

你可以利用intValue方法对Integer类(从Number实际上继承),即

sum += element.intValue(); 

的之所以不能使用sum += element就是因为编译器不知道具体的类T是什么,所以它不能autobox。 T可能Integer,但是您已声明TT extends Integer,因此编译器不知道实际上是什么子类T

现在,在你的情况下,它会变得有点有趣,因为Integer是最后一堂课。你可能会争辩说,编译器应该能够找出T永远是Integer。它显然不会这样做。

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

class Sum implements Visitor<Integer> { 
    public void visit(Integer i) { 
     sum += i; 
    } 
} 

这应该工作得很好。