【发布时间】:2012-10-21 04:41:54
【问题描述】:
我正在使用一些带有泛型的代码,我不确定为什么会引发编译错误。
public static void main(String[] args) {
System.out.print("s");
setInteger(prepareNumber("1")); // Error here! solved by casting: setInteger((Integer)prepareNumber("1"))
Integer c = prepareInteger("1");
System.out.print(c);
}
public static Integer prepareInteger(Object number) {
return prepareNumber(number).intValue();
}
private static <T extends Number> T prepareNumber(Object number) {
T returnValue = null;
// handle a blank number
if (number == null || !NumberUtils.isNumber(number.toString())) {
returnValue = null;
} else {
if (number.toString().contains(".")) {
returnValue = (T) Double.valueOf(number.toString());
} else {
returnValue = (T) Integer.valueOf(number.toString());
}
}
return returnValue;
}
private static void setInteger(Integer a){
}
只需进行强制转换即可轻松解决此问题,但这是不希望的,因为泛型应该检测到方法需要 Integer 并且应该提供返回值本身而不是超类型。
PS:不要介意解析代码,只是测试的东西。
谢谢!
【问题讨论】:
-
错误信息说明了什么?这不是不言自明吗?
-
prepareNumber 返回一个数字,它可能不是整数。事实上,如果
number.toString().contains("."),您的“修复”将引发 ClassCastException。真正的问题是,为什么要传递 setInteger 可能不是 Integer 的东西? -
实际上,
T method() 本质上说:“此方法返回的东西可以在编译时转换为每种引用类型”,因此该方法可能返回的唯一值是 null。事实上,您的代码会引发与泛型相关的警告 (javac -Xlint:unchecked);并且 Java 不保证出现泛型相关警告时的类型安全。 prepareNumber实际上没有理由是通用的:普通的Number prepareNumber(Object number)就可以了。 -
@JB : 该方法引发以下错误:Test 类型中的方法 setInteger(Integer) 不适用于参数 (Number)
-
@Ignis :希望它是通用的原因基本上是因为我将整数或双精度数作为字符串,我需要解析它们并将它们放入对象的设置器中,无论是属性.