Java:将对象转换为generics类型

在Java中从Object转换为其他类型时,为什么第二行会产生与转换相关的警告,但第一行不会?

void a(Object o) { Integer i = (Integer) o; List list = (List) o; } /*Type safety: Unchecked cast from Object to List*/ 

这是因为由于类型擦除,在执行时不会真正检查对象是否为List 。 它真的只是将它投射到List 。 例如:

 List strings = new ArrayList(); strings.add("x"); Object o = strings; // Warning, but will succeeed at execution time List integers = (List) o; Integer i = integers.get(0); // Bang! 

有关详细信息,请参阅Angelika Langer的Java Generics FAQ ,尤其是类型擦除部分 。

为清楚起见,让我稍微重写一下这些例子……

我会说, 两者之间的关键区别

 void a(Object o) { Integer i = (Integer) o; ... } 

 void a(Object o) { List list = (List) o; ... } 

是的,鉴于存在类型错误 ,第一个强制转换将始终在执行时立即抛出 RuntimeException(特别是ClassCastException)。

虽然第二个可能没有 – 只要输入参数o是任何类型的List ,执行就会继续进行, 尽管有不正确的强制转换。

代码是否会在某个地方稍后抛出exception,取决于您对列表的处理方式。

但无论如何,可能不会在制作演员阵容的行上抛出exception ,而是在其他地方抛出exception (可能是难以追踪的错误)或根本不抛出

这就是我所理解的,是编译器设计者在第二种情况下认为适当的警告的原因。

Jon的答案是正确的,但偶尔你无法解决这个警告(比如当你使用遗留API时)。 在这些情况下,您可以像这样抑制警告:

 @SuppressWarnings("unchecked") List list = (List) someApiThatReturnsNonGenericList();