代码之家  ›  专栏  ›  技术社区  ›  Justin Garrick

在Java中安全地遍历原始迭代器?

  •  7
  • Justin Garrick  · 技术社区  · 14 年前

    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;
        ...
    }
    

    EDIT:我意识到我可以在else块中捕获/记录异常,我正在寻找(希望)与ColinD在下面提到的Java语言等价的东西。

    4 回复  |  直到 14 年前
        1
  •  7
  •   ColinD    14 年前

    Guava 使这一点与它的 Iterators.filter(Iterator<?>, Class<T>) Iterator<T> T

    Iterator<ActualObject> children = Iterators.filter(element.getChildElements(),
        ActualObject.class);
    

    显然,您可以遍历生成的迭代器,而无需将每个元素强制转换为 ActualObject ClassCastException .

        2
  •  2
  •   Nathan Hughes    14 年前

    处理它的简单方法就是强制转换它,并确保,如果类型在将来与您期望的不同,将引发异常并通知您。你会想检查一下,不管你是如何记录异常的工作,异常会找到它的方式,日志文件。例外的存在是为了告诉你一些事情不是你所期望的,让他们做他们的工作。

        3
  •  2
  •   Sean Patrick Floyd    14 年前

    Iterator<?> children = element.getChildElements();
    // no null check needed. If an api that supposedly
    // returns an iterator actually returns null, it's a bad
    // API, don't use it
    while (children.hasNext()) {
        Object obj = children.next();
        if (obj instanceof ActualObject)
            doStuffWith((ActualObject)obj);
        // we know it's of the right type so we might
        // as well put the cast in the method call.
    }
    

    所以归结起来就是:

    Iterator<?> children = element.getChildElements();
    while (children.hasNext()) {
        Object obj = children.next();
        if (obj instanceof ActualObject)
            doStuffWith((ActualObject)obj);
    }
    

    我想说这也不算太糟。

    if块下面也应该有else块。 大致如下:

    else{
        log.warn("Expected type: " + ActualObject.class + ", but got " + obj);
    }
    
        4
  •  1
  •   pkaeding    14 年前

    因为如果遇到迭代器返回的对象不是 ActualObject ,然后我就投了它,并有一个捕捉块来处理可能的问题 ClassCastException