在Java中,从一个对象转换为其他类型时,为什么第二行会产生与转换相关的警告,而第一行不会?
void a(Object o) {
Integer i = (Integer) o;
List<Integer> list = (List<Integer>) o;
}
/*Type safety: Unchecked cast from Object to List<Integer>*/
这是因为由于类型擦除,在执行时对象实际上不会被检查是否为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!
请查看Angelika Langer的Java泛型FAQ以获取更多信息,特别是类型擦除部分。
void a(Object o) {
Integer i = (Integer) o;
...
}
and
void a(Object o) {
List<Integer> list = (List<Integer>) o;
...
}
假设存在类型错误,第一次转换将在执行时立即抛出运行时异常(具体来说是ClassCastException)。
而只要输入参数o是任何类型的List<?>
,第二个可能就不会——尽管有错误转换,执行也会继续进行。
代码是否会在稍后抛出异常取决于您对列表的操作。
但不管怎样,在强制类型转换处不会抛出异常,而是可能在其他地方(这可能是一个难以跟踪的错误)或根本不抛出异常。
这就是我理解的,编译器设计者认为仅在第二种情况下使用警告的原因。
Integer
。第一行代码可能会抛出异常,就像第二个代码一样,如果o
不是一个List
的话也可能会抛出异常。 - Hot LicksJon的答案是正确的,但有时你无法避免这个警告(比如在使用遗留API时)。在这种情况下,你可以这样禁止警告:
@SuppressWarnings("unchecked")
List<Integer> list = (List<Integer>) someApiThatReturnsNonGenericList();