hasNext() 返回 false 时 next() 必抛 NoSuchElementException;必须用 while (it.hasNext()) { it.next(); } 模式,不可先判断后循环;for-each 是其语法糖;安全删除须用 it.remove();泛型擦除下 next() 可能触发 ClassCastException。

hasNext() 返回 false 时 next() 一定抛异常
调用 next() 前必须确保 hasNext() 返回 true,否则会抛出 NoSuchElementException。这不是“可能出错”,而是 Java 规范强制要求的行为——Iterator 不做防御性检查,它信任调用方。
- 常见错误:在 while 循环外多调一次
next(),比如先if (it.hasNext()) it.next();再进循环 - 正确模式只有一种:始终把
hasNext()放在循环条件里,next()只出现在循环体内 - 注意:
hasNext()是“探测”操作,不移动指针;next()才真正消费元素并推进内部状态
for-each 循环底层就是 hasNext + next 的封装
写 for (String s : list) 时,编译器自动展开为标准的 Iterator 模式。这意味着你遇到的空指针、并发修改异常(ConcurrentModificationException),根源和手写 hasNext/next 完全一致。
- 如果集合本身是
null,调用list.iterator()就会 NPE,不是hasNext()报的 - 遍历中修改原集合(如
list.remove(x))会触发 fail-fast 机制,hasNext()或next()下一次调用就炸 - 安全删除必须用
it.remove(),且只能在刚调用过next()后立即执行
泛型擦除后 next() 的返回类型仍是 Object,但编译器帮你强转了
原始类型迭代器(如 Iterator 而非 Iterator<string></string>)调用 next() 返回 Object,需要手动转型;而泛型版本由编译器插入隐式转换,运行时仍存在类型擦除风险。
- 若集合实际存了
Integer却声明为Iterator<string></string>,编译通过,运行到(String) it.next()时才抛ClassCastException -
hasNext()不涉及类型,永远安全;next()是唯一可能触发运行时类型异常的 Iterator 方法 - 用 IDE 的泛型检查和单元测试覆盖边界值(如 null 元素),比依赖
hasNext()判断更关键
自定义 Iterator 时 hasNext 和 next 必须严格同步状态
实现 Iterator 接口时,hasNext() 和 next() 共享同一套内部索引或游标。常见 bug 是两个方法各自维护一套计数器,导致逻辑错位。
- 典型错误:在
hasNext()里判断index ,但在 <code>next()里忘了index++或写成++index导致跳过元素 - 推荐做法:把“是否还有下一个”的判断逻辑抽成私有方法,
hasNext()直接返回它,next()在返回前调用它并更新状态 - 如果迭代器支持
remove(),还要确保它不影响hasNext()对后续元素的判断
hasNext() 返回 false,这个 Iterator 就彻底失效了;而 next() 的每一次调用,都默认你已用 hasNext() 确认过它的合法性。

















