一尘不染

Java:强制转换为类型参数

java

我有以下两节课:

public class GenericNumberOperation {
    public GenericNumberOperation() {} 
    public <T extends Number> T getSomeValue (boolean tf) {
      T number;
      if(tf) {
          number = new Double(1.0);
      }
      else {
           number = new Integer(11);
      }
      return (T) number;
   }
}

和:

public class GenericNumberTest {
    public GenericNumberTest() {}

    public static void main(String[] args) {
        GenericNumberOperation gno = new GenericNumberOperation();
        Double d = gno.getSomeValue(true);
        Integer i = gno.getSomeValue(false);
    }
 }

当我运行测试时,一切都是笨拙的。如果我将类型参数化更改为:

public <T> T getSomeValue(boolean tf)

编译器抱怨,报告:

错误:类型不兼容的整数不能转换为T number = new Integer(11);
其中T是类型变量T扩展了在方法getSomeValue(boolean)中声明的Object

它同样对Double有所抱怨。为什么?

编辑:我犯了一个错误。这实际上是有效的代码。

public class GenericNumberOperation {
    public GenericNumberOperation() {} 
    public <T extends Number> T getSomeValue (boolean tf) {
      Number number;
      if(tf) {
          number = new Double(1.0);
      }
      else {
           number = new Integer(11);
      }
      return (T) number;
   }
}

现在我明白了@Sotirios在干什么。


阅读 591

收藏
2020-12-03

共1个答案

一尘不染

忘记您要使用它做什么。我们仅从语言角度看待这一点。

报关单

public <T extends Number> T getSomeValue (boolean tf) {

定义一个T以限制的新类型Number。这意味着,一个呼叫者只能绑定Number或任何亚型NumberT调用方法时。在该方法中,您不知道该类型可能是什么。

因此,你不能做

T number = new Double(1.0);

因为你不知道那TDouble。如果我将方法调用为

Float f = genOp.getSomeValue(true);

T应该是Float。编译器不能保证类型安全,因此拒绝它(方法内的分配,如果允许的话,ClassCastException将在运行时抛出)。如果使用强制转换,则是告诉编译器您确定自己在做什么。它会警告您,但会信任您。

同样,声明

public <T> T getSomeValue(boolean tf)

定义一个T无界的新类型。这意味着您可以将任何类型绑定到T,这使问题更加严重。我现在可以做

String f = genOp.getSomeValue(true);
2020-12-03