Mik*_*ike 16 java generics casting
在Java中从Object转换为其他类型时,为什么第二行会产生与转换相关的警告,但第一行不会?
void a(Object o) {
Integer i = (Integer) o;
List<Integer> list = (List<Integer>) o;
}
/*Type safety: Unchecked cast from Object to List<Integer>*/
Run Code Online (Sandbox Code Playgroud)
Jon*_*eet 24
这是因为该对象不会真的被用于作为一个检查List<Integer>
,在由于执行时间类型擦除.它真的只是投射它List
.例如:
List<String> strings = new ArrayList<String>();
strings.add("x");
Object o = strings;
// Warning, but will succeeed at execution time
List<Integer> integers = (List<Integer>) o;
Integer i = integers.get(0); // Bang!
Run Code Online (Sandbox Code Playgroud)
有关详细信息,请参阅Angelika Langer的Java Generics FAQ,尤其是类型擦除部分.
Jon的答案是正确的,但偶尔你无法解决这个警告(比如当你使用遗留API时).在这些情况下,您可以像这样抑制警告:
@SuppressWarnings("unchecked")
List<Integer> list = (List<Integer>) someApiThatReturnsNonGenericList();
Run Code Online (Sandbox Code Playgroud)
为清楚起见,让我稍微重写一下这些例子......
我会说,两者之间的关键区别:
void a(Object o) {
Integer i = (Integer) o;
...
}
Run Code Online (Sandbox Code Playgroud)
和
void a(Object o) {
List<Integer> list = (List<Integer>) o;
...
}
Run Code Online (Sandbox Code Playgroud)
是的,鉴于存在类型错误,第一个强制转换将始终在执行时立即抛出 RuntimeException(特别是ClassCastException).
虽然第二个可能不是 - 只要输入参数o是任何类型List<?>
,执行将继续执行,尽管不正确的强制转换.
代码是否会在某个地方稍后抛出异常,取决于您对列表的处理方式.
但无论如何,可能不会在构建转换的行上抛出异常,而是在其他地方抛出(可能是难以追踪的错误)或根本不抛出异常.
这就是我所理解的,是编译器设计者在第二种情况下认为适当的警告的原因.