我有一个通用方法T foo(T)
,它根据参数的实际类型执行不同的操作。以下示例说明了同样的问题。 (请参阅下文,了解我在代码中实际执行的操作。)
<T extends Number> T foo(T a) {
if (a instanceof Integer) {
return ((Integer) a) + 1;
} else if (a instanceof Double) {
return ((Double) a) + 1;
} else {
throw new IllegalArgumentException();
}
}
这不违反返回类型的要求,但javac
不接受。问题是例如只有在return ((Integer) a) + 1;
为T
时才会执行Integer
,但编译器不能(根据JLS)推断出这一点,因此期望T
是return
传递给int
。其中的表达式为T
,无法转换为{{1}}。
有没有办法处理这种情况而不诉诸未经检查的演员?
我在代码中实际做了什么:在应用程序中,有一个通用接口,用于封装某些值。对于不同的值类型,该接口有不同的专用实现,我尝试编写的方法应该动态地选择正确的实现。
答案 0 :(得分:3)
如果你在运行时进行类型检查a
,那么你就是在打败泛型。但是泛型无论如何都不能使用数学运算符,因为这些运算符使用基元和类型参数使用引用类型。您的解决方法不适用于编译器,因为T
在编译时可能是任何Number
类型,因此编译器不允许您在认为可能时返回Integer
任何Number
类型。
相反,我会重载两个非通用foo
方法 - 一个使用int
,另一个使用double
。这些方法都不是通用的,每个方法都只能执行自己的操作。
答案 1 :(得分:0)
这不是对泛型的正确使用。您应该使用method overloading代替