Java:将对象转换为泛型类型
Posted
技术标签:
【中文标题】Java:将对象转换为泛型类型【英文标题】:Java: Casting Object to a generic type 【发布时间】:2010-11-12 22:57:18 【问题描述】:在 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>*/
【问题讨论】:
第二行会产生警告,因为只有泛型会产生这样的警告。第一个不包含泛型,因此没有警告。 【参考方案1】:这是因为由于类型擦除,在执行时不会真正检查对象是否为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's Java Generics FAQ,尤其是type erasure section。
【讨论】:
【参考方案2】:Jon 的答案是正确的,但有时您无法避开该警告(例如,当您使用旧版 API 时)。在这些情况下,您可以像这样抑制警告:
@SuppressWarnings("unchecked")
List<Integer> list = (List<Integer>) someApiThatReturnsNonGenericList();
【讨论】:
【参考方案3】:为了清楚起见,让我稍微重写一下例子……
我想说,关键的区别:
void a(Object o)
Integer i = (Integer) o;
...
和
void a(Object o)
List<Integer> list = (List<Integer>) o;
...
是,鉴于存在类型错误,第一次强制转换在执行时总是立即抛出 RuntimeException(特别是 ClassCastException)。
而第二个可能不会——只要输入参数 o 是任何类型的List<?>
,执行就会继续,尽管不正确演员表。
代码是否会在某处稍后抛出异常,取决于您对列表执行的操作。
但无论如何,异常可能不会被抛出在进行强制转换的行,而是在其他地方(这可能是一个难以追踪的错误)或根本不抛出。
这就是我的理解,这就是编译器设计者认为警告仅适用于第二种情况的原因。
【讨论】:
第一个不会总是抛出 CastClassException。传入的对象很可能是Integer
。第一行可能会抛出异常,就像第二行可能会在 o
不是 List
时抛出异常。
@Hot Licks :是的,这就是为什么我在上面写了“鉴于存在类型错误”——我什至用粗体表示;)以上是关于Java:将对象转换为泛型类型的主要内容,如果未能解决你的问题,请参考以下文章
无法将类型“Int”的值转换为泛型中的预期参数类型“Int”