Java:投射到一个类型参数 [英] Java: Casting to a type parameter
问题描述
我有以下两个类:
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屋!