Java:将对象转换为泛型类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4169806/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 12:16:41  来源:igfitidea点击:

Java: Casting Object to a generic type

javagenericscasting

提问by Mike

In Java when casting from an Object to other types, why does the second line produce a warning related to the cast, but the first one doesn't?

在 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>*/

采纳答案by Jon Skeet

It's because the object won't reallybe checked for being a List<Integer>at execution time due to type erasure. It'll really just be casting it to List. For example:

这是因为由于类型擦除,在执行时不会真正检查对象是否为 a 。它真的只是将它投射到. 例如: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!

See Angelika Langer's Java Generics FAQfor more info, particularly the type erasure section.

有关更多信息,请参阅Angelika Langer 的 Java 泛型常见问题解答,尤其是类型擦除部分

回答by Brad Cupit

Jon's answer is the right one, but occasionally you can't get around that warning (like when you're working with a legacy API). In those cases you can suppress the warning like so:

Jon 的答案是正确的,但有时您无法绕过该警告(例如当您使用旧 API 时)。在这些情况下,您可以像这样抑制警告:

@SuppressWarnings("unchecked")
List<Integer> list = (List<Integer>) someApiThatReturnsNonGenericList();

回答by Rop

For clarity, let me slightly rewrite the examples...

为了清楚起见,让我稍微改写一下例子......

I would say, the cruxial differencebetween:

我会说,以下之间的关键区别

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

and

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

is that, given that there is a type-error, the first cast will always immediately throwa RuntimeException (specifically, a ClassCastException) when executed.

也就是说,如果存在类型错误,第一次强制转换在执行时总是会立即抛出RuntimeException(特别是 ClassCastException)。

While the second one mightnot -- as long as the input parameter o is any kind of List<?>, execution will just proceed, in spiteof an incorrect cast.

虽然第二个可能不会——只要输入参数 o 是任何一种List<?>,执行就会继续,尽管转换不正确。

Whether the code will somewhere laterthrow an exception or not, depends upon what you do with the list.

代码以后是否会在某处抛出异常,取决于您对列表的处理方式。

But regardless, an Exception might not be thrown at the line where the cast was made, but somewhere else (which might be a difficult bug to trace down) or not at all.

但无论如何,异常可能不会在进行演员表的那一行抛出,而是在其他地方(这可能是一个难以追踪的错误)或根本不抛出

That's what I understand, is the reason the compiler-designers considered a warning appropriate in the second case only.

这就是我的理解,这就是编译器设计者认为仅适用于第二种情况的警告的原因。