Java:投射到一个类型参数 [英] Java: Casting to a type parameter

查看:62
本文介绍了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;


$ / code $ / pre
$ b $< / b>

  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 extends在方法getSomeValue(boolean)中声明的对象

它类似地抱怨Double。为什么?



编辑:
我犯了一个错误。

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

现在我明白@Sotirios正在接受什么。

解决方案

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

声明

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

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



因此,您不能这样做

  T number = new Double(1.0); 

因为您不知道 T Double 。如果我以

 浮动f = genOp.getSomeValue(true); 

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



同样,声明

  public< T> T getSomeValue(boolean tf)

定义了一个新类型 T 这是无界的。这意味着您可以将任何类型绑定到 T ,这会使问题更加严重。我现在可以做
$ b $ pre $ String f = genOp.getSomeValue(true);


I have the following two classes:

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

And:

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

When I run the test, everything is hunky-dory. If I change the type parameterization to:

public <T> T getSomeValue(boolean tf)

The compiler complains, reporting:

error: incompatible types Integer cannot be converted to T number = new Integer(11); where T is a type variable T extends Object declared in method getSomeValue(boolean)

It complains similarly about the Double. Why?

EDIT: I made a mistake. This is actually the code that works.

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

And now I understand what @Sotirios was getting at.

解决方案

Forget about what you're trying to use this for. We're only going to look at this from a language perspective.

The declaration

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

defines a new type T that is bounded by Number. That means that a caller can only bind Number or any subtype of Number to T when invoking the method. Within the method, you don't know what that type might be.

You therefore can't do

T number = new Double(1.0);

because you don't know that T is Double. If I invoked the method as

Float f = genOp.getSomeValue(true);

T should have been Float. The compiler can't guarantee type safety and therefore rejects it (the assignment within the method, if it had been allowed, a ClassCastException would have been thrown at runtime). If you use a cast, you're telling the compiler that you're sure about what you're doing. It'll warn you, but it will trust you.

Similarly, the declaration

public <T> T getSomeValue(boolean tf)

defines a new type T that is unbounded. That means that you can bind any type to T, which makes the problem even greater. I can now do

String f = genOp.getSomeValue(true);

这篇关于Java:投射到一个类型参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆