【问题标题】:Using generics causes unchecked conversion warning使用泛型会导致未经检查的转换警告
【发布时间】:2010-12-03 08:45:18
【问题描述】:

我有以下代码

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

导致此警告

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

引用的方法是

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

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

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

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

因为编译器无法提前保证安全,但如果可能的话我宁愿避免使用SuppressWarnings...有没有更好的方法?

编辑:getChildElements() 记录在 here

【问题讨论】:

  • 很高兴 Java 泛型允许您的代码编译。就我个人而言,我会将警告留在那里 - 这是一个完全有效的警告。

标签: java generics casting


【解决方案1】:

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

我们的编码标准是仅当我们能够证明代码是类型安全的时才抑制警告 - 我们将包外的任何调用视为黑盒,并且不依赖任何 cmets原始集合的内容。因此,压制极为罕见。通常,如果代码是类型安全的,编译器可以确定它,尽管有时我们必须给它一些帮助。少数例外涉及不会从私有上下文中“逃逸”的泛型类型数组。

如果您不完全信任第三方库,请创建一个新集合,并将内容投射到OMEElementImpl 后添加。这样,如果库中存在错误,您会立即发现它,而不是让一些在时间和空间上相距遥远的代码被 ClassCastException 炸毁。

例如:

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());

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


更新:尤其是在这种情况下,假设getChildElements 的结果是OMElementImpl 的迭代器似乎极具风险。充其量,您可能会认为它们是 OMElement,这只是类中隐含的,而不是具体方法中的任何内容。

【讨论】:

  • 像这样验证第三方库返回的集合的内容是个好建议。
  • 作为创建新集合的替代方法,请参阅 Google 集合中的 Iterables.transform google-collections.googlecode.com/svn/trunk/javadoc/com/google/…
  • 好吧,我是一名新的初级开发人员,我确信在这种特殊情况下可以做出假设;我(和我的技术主管,就此而言)只是讨厌看到这个小警告图标。 +1/接受提供良好的一般建议。
猜你喜欢
  • 1970-01-01
  • 2013-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多