在通用类中进行转换

时间:2013-08-19 10:43:24

标签: java generics casting

以下是代码段。

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值。

有什么原因吗?请解释一下。感谢。

2 个答案:

答案 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的实例。”。

所以编译器已经警告你这不起作用,但忽略了警告。由于类型擦除,它不起作用。