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

时间:2009-10-02 15:03:30

标签: java generics casting

我有以下代码

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

导致此警告

  

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

引用的方法是

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

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

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

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

因为编译器无法提前保证安全性,但我希望尽可能避免使用SuppressWarnings ...有更好的方法吗?

编辑:getChildElements()记录在案here

1 个答案:

答案 0 :(得分:16)

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

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

如果您不完全信任第三方库,请创建一个新集合,并在将其转换为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,并且这只是从类中隐含的,而不是特别是方法上的任何内容。