java 使用泛型会导致未经检查的转换警告

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1510100/
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-10-29 16:49:55  来源:igfitidea点击:

Using generics causes unchecked conversion warning

javagenericscasting

提问by Pops

I have the following code

我有以下代码

String innerText = null;
innerText = this.getException(detail.getChildElements());

causing this warning

导致此警告

Type safety: The expression of type Iterator needs unchecked conversion to conform to Iterator

类型安全:Iterator 类型的表达式需要未经检查的转换才能符合 Iterator

The referenced method is

引用的方法是

private String getException(Iterator<OMElementImpl> iterator) { ... }

The other method, getChildElements(), is in a JAR file that I can't touch. There are no other warnings or errors.

另一种方法getChildElements()是在我无法触及的 JAR 文件中。没有其他警告或错误。

From Googling, it seems like the usual way to get rid of this sort of warning is

从谷歌搜索,似乎摆脱这种警告的常用方法是

@SuppressWarnings("unchecked")
String innerText = this.getException(detail.getChildElements());

because the compiler can't guarantee safety ahead of time, but I'd prefer to avoid using SuppressWarningsif possible... is there a better way?

因为编译器不能提前保证安全,但我更愿意尽可能避免使用SuppressWarnings......有没有更好的方法?

EDIT: getChildElements()is documented here

编辑:getChildElements()记录在这里

回答by erickson

You cansuppress the warning, but if you do so, you are relying 100% on the third-party library, and discarding the assurance of Java generic types: that any ClassCastExceptionraised at runtime will occur right at an explicit cast.

可以取消警告,但如果您这样做,您将 100% 依赖第三方库,并放弃 Java 泛型类型的保证:任何ClassCastException在运行时引发的都将在显式转换时发生。

Our coding standard is to suppress warnings only when we can provethe code is type safe—and we treat any calls outside the package as a black box, and don't rely on any comments about the content of a raw collection. So, suppression is extremely rare. Usually, if the code is type safe, the compiler can determine it, although sometimes we have to give it some help. The few exceptions involve arrays of generic type that don't "escape" from a private context.

我们的编码标准是只有在我们可以证明代码是类型安全的时候才抑制警告——并且我们将包外的任何调用视为黑盒,并且不依赖任何关于原始集合内容的注释。所以,压制是极其罕见的。通常,如果代码是类型安全的,编译器可以确定它,尽管有时我们必须给它一些帮助。少数例外涉及不会从私有上下文中“转义”的泛型类型的数组。

If you don't fully trust the third-party library, create a new collection, and add the contents after casting them to OMEElementImpl. That way, if there is a bug in the library, you find out about it right away, rather than having some code far distant in time and space blow up with a ClassCastException.

如果您不完全信任第三方库,请创建一个新集合,然后将内容转换为OMEElementImpl. 这样,如果库中存在错误,您会立即发现它,而不是让一些时间和空间遥远的代码因ClassCastException.

For example:

例如:

Iterator<?> tmp = detail.getChildElements();
Collection<OMElementImpl> elements = new ArrayList<OMElementImpl>();
while (tmp.hasNext())
  elements.add((OMElementImpl) tmp.next()); /* Any type errors found here! */
String innerText = getException(elements.iterator());

Remember, generics were not invented to make code look pretty and require less typing! The promise of generics is this: Your code is guaranteed to be type-safe if it compiles without warnings.That is it. When warnings are ignored or suppressed, code without a cast operator can mysteriously raise a ClassCastException.

请记住,发明泛型并不是为了使代码看起来漂亮并且需要更少的输入!泛型的承诺是这样的:如果你的代码在没有警告的情况下编译,它就保证是类型安全的。这就对了。当警告被忽略或抑制时,没有强制转换运算符的代码可能会神秘地引发ClassCastException.



Update:In this case, especially, it seems extremely risky to assume that the result of getChildElementsis a iterator of OMElementImpl. At best, you might assume that they are OMElement, and that's only implied from the class, not anything on the method in particular.

更新:特别是在这种情况下,假设 的结果getChildElements是 的迭代器似乎非常冒险OMElementImpl。充其量,您可能会假设它们是OMElement,并且这只是从类中隐含的,而不是特别针对方法的任何内容。