Java:转换为类型参数

时间:2015-10-14 17:07:10

标签: 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;
   }
}

并且:

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整数(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的目标。

2 个答案:

答案 0 :(得分:5)

忘记你正在尝试使用它的内容。我们只是从语言的角度来看待这个问题。

声明

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

定义了一个由T限定的新类型Number。这意味着调用者只能在调用方法时将NumberNumber的任何子类型绑定到T。在该方法中,您不知道该类型可能是什么。

你无法做到

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);

答案 1 :(得分:-2)

@Sotirios Delimanolis写道,你甚至无法运行该代码。

试试这个:

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