编译器依赖于类型安全性进行假设并进行转换/优化。不幸的是,类型安全性可以通过未经检查的强制转换来破坏。如果您的程序包含不正确的未经检查的强制转换,则不清楚编译器应该做什么。理想情况下,它应在未检查的强制转换的确切点进行运行时检查,在您的示例中
Object为
T。但是由于擦除,这是不可能的,而这并不是类型系统的一部分。
在示例中的其他任何地方,类型都是健全的,因此编译器可以假定
getValue()确实返回a
String,无需再次检查。但是进行检查也是合法的,就像Eclipse编译器所做的那样(可能是因为它将返回值分配给
String本地temp变量)。
因此,有个坏消息是,如果您的程序包含不正确的未经检查的强制转换,则其行为是不确定的…。因此,请通过严格的推理确保所有未经检查的强制转换都是正确的。
一个好的做法是检查所有未选中的强制类型转换,以便您可以合法地取消选中未选中的警告。例如
<T> T getValue(Map<String, Object> dataMap, String value, Class<T> type) { Object value = dataMap.get(value); if(value!=null && !type.isInstance(value)) // check! throw new ClassCastException(); @SuppressWarning("unchecked") T t = (T)value; // this is safe, because we've just checked return t; }看到我对类似问题的回答:Java中的惰性类转换?



