Java:转换为类型参数

Dav*_*vid -2 java generics

我有以下两个类:

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;
   }
}
Run Code Online (Sandbox Code Playgroud)

和:

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);
    }
 }
Run Code Online (Sandbox Code Playgroud)

当我进行测试时,一切都很笨拙.如果我将类型参数更改为:

public <T> T getSomeValue(boolean tf)
Run Code Online (Sandbox Code Playgroud)

编译器抱怨,报告:

错误:不兼容的类型整数不能转换为T number = new Integer(11); 其中T是类型变量T extends在方法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;
   }
}
Run Code Online (Sandbox Code Playgroud)

现在我明白了@Sotirios的目标.

Sot*_*lis 5

忘记你正试图用它做什么.我们只是从语言的角度来看这个.

声明

public <T extends Number> T getSomeValue (boolean tf) {
Run Code Online (Sandbox Code Playgroud)

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

你因此做不到

T number = new Double(1.0);
Run Code Online (Sandbox Code Playgroud)

因为你不知道那T是什么Double.如果我调用该方法为

Float f = genOp.getSomeValue(true);
Run Code Online (Sandbox Code Playgroud)

T本来应该的Float.编译器不能保证类型安全,因此拒绝它(方法中的赋值,如果允许的话,ClassCastException将在运行时抛出).如果你使用演员表,你告诉编译器你确定你在做什么.它会警告你,但它会信任你.

同样,声明

public <T> T getSomeValue(boolean tf)
Run Code Online (Sandbox Code Playgroud)

定义一个T无限的新类型.这意味着您可以绑定任何类型T,这使问题更大.我现在可以做

String f = genOp.getSomeValue(true);
Run Code Online (Sandbox Code Playgroud)

  • @David您的第一个代码段不应该像您显示的那样编译. (4认同)
  • @David [你不能运行你认为正在运行的东西.](http://ideone.com/0wTnW6) (3认同)