泛型在Java中安全地遍历原始迭代器?
我使用的第三方库返回原始迭代器,例如
Iterator<?> children = element.getChildElements();
我知道实际的类型,但我不一定相信第三方lib将来会坚持使用它。有两种(我能想到的)有点风险的方法来解决这个问题:
@SuppressWarnings("unchecked")
Iterator<ActualObject> currentChildren = (Iterator<ActualObject>)currentElement.getChildElements();
或
Iterator<?> children = element.getChildElements();
while (null != children && children.hasNext()) {
ActualObject child = (ActualObject)children.next(); //Possible ClassCastException @ runtime
...
}
我能想到的遍历这种迭代器的唯一“安全”方法是:
Iterator<?> children = element.getChildElements();
while (null != children && children.hasNext()) {
Object obj = children.next();
ActualObject child = null;
if (obj instanceof ActualObject)
child = (ActualObject)obj;
...
}
这似乎过于冗长。有没有一种更好但同样“安全”的方法来遍历原始迭代器强>
编辑:我意识到我可以在else块中捕获/记录异常,我正在寻找(希望)一种与ColinD在下面提到的Java语言等价的语言
# 1 楼答案
Guava通过其Iterators.filter(Iterator<?>, Class<T>)方法使这一过程变得简单。它返回一个不可修改的
Iterator<T>
,基本上只跳过给定迭代器中不是T
类型实例的每个元素:显然,您可以遍历生成的迭代器,而无需将每个元素强制转换为
ActualObject
,也无需担心ClassCastException
# 2 楼答案
如果遇到迭代器返回的对象不是
ActualObject
的实例,那么听起来您希望停止执行并抛出异常,因此我将强制转换它,并使用catch块来处理可能的ClassCastException
# 3 楼答案
处理它的简单方法是强制转换它,并确保如果类型与您将来期望的类型不同,将引发异常并通知您。您将要检查,无论您如何记录异常,异常都是有效的,并且异常将进入日志文件。例外的存在是为了告诉你一些事情不是你所期望的,让他们做他们的工作
如果您悄悄地跳过不是预期类型的元素,那么您可能会丢失所需的数据,对我来说,这听起来不是一个好的解决方案
# 4 楼答案
您的上一个版本似乎是一个不错的选择,但我想我们可以改进一下:
所以归结起来就是:
我想说这还不错
编辑:
if块下面可能也应该有一个else块。 大致如下: