2009-10-02 29 views
7

我有以下代码使用泛型导致未检查转换警告

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

+5

只是很高兴Java泛型允许你的代码编译。我个人会在那里留下警告 - 这是一个完全有效的警告。 – 2009-10-02 15:11:31

回答

16

可以抑制警告,但如果你这样做,你是在第三方库依托100%,并放弃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,而这只是从班级暗示的,而不是特别的方法。

+0

验证这样的第三方库返回的集合的内容是很好的建议。 – 2009-10-02 15:24:38

+0

作为创建新集合的替代方法,请参阅Google Collections中的“Iterables.transform”http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Iterables.html#transform( java.lang.Iterable,%20com.google.common.base.Function) – 2009-10-02 15:36:16

+0

嗯,我是一个新的初级开发人员,并且已经确信可以在这个特定情况下做出假设;我(和我的技术主管,就此而言)只是看不到这个小小的警告图标。 + 1 /被接受为提供良好的一般建议,但。 – Pops 2009-10-06 13:08:09

相关问题