以下是代码段。
public class Operand<T> {
private OperandStore store;
private final int operandType, operandId;
public Operand( int operandType, int operandId, OperandStore store ) {
this.operandId = operandId;
this.operandType = operandType;
this.store = store;
}
@SuppressWarnings( "unchecked" )
public T evaluate() {
try {
return ( T ) store.getValue( operandType, operandId );
}
catch ( Exception e ) {
return null;
}
}
}
我的getValue
方法:
public Object getValue(int operandType, int operandId ) {
// return some value from a <String, Object> hashmap based on some condition
}
当我创建上述类的对象时,如下所示:
Operand<Integer> obj = new Operand<>(1,1,store);
...并确保store.getValue( operandType, operandId )
返回一个字符串,我预计在try
块中会发生错误,但不会发生。它会返回string
值。
有什么原因吗?请解释一下。感谢。
答案 0 :(得分:3)
您是仅调用obj.evaluate()
还是调用Integer x = obj.evaluate()
例如:
OperandStore store = new OperandStore();
Operand<Integer> obj = new Operand<>(1,1,store);
Integer x = obj.evaluate();
这会因ClassCastException
而失败,因为它存在Java意识到问题的地方。
在此之前它不会因type erasure而失败。基本上,运行时T的类型只是java.lang.Object,这就是为什么向T转换任何东西似乎都有效,但是一旦你试图在你的调用站点中使用T,你会在Java尝试做的时候得到异常合成铸造。
答案 1 :(得分:3)
删除@SuppressWarnings( "unchecked" )
,然后阅读警告。
它告诉你“Unchecked cast:'java.lang.Object'到T”。
未选中的强制转换意味着:“强制转换不会检查该对象是否是T的实例。”。
所以编译器已经警告你这不起作用,但忽略了警告。由于类型擦除,它不起作用。