核心是让强转后的迭代器无法修改容器状态:用private static内部类、final私有状态、独立快照副本、禁用remove/set/add并抛异常、返回深拷贝而非可变视图。

在自定义可迭代容器中,防止外部通过强转修改内部迭代状态,核心不是“阻止强转本身”(Java 无法禁止类型强转),而是让强转后得到的对象**无实际修改能力**——即切断强转所得引用与容器真实状态的关联。关键在于:迭代器必须完全私有化其状态,不暴露任何可被篡改的字段或可变视图。
迭代器类必须声明为 private static 内部类
避免外部获取到迭代器实例后,通过反射或强转访问其内部游标、栈、索引等字段:
- 用 private static class MyIterator implements Iterator<T>,确保类不可被外部继承或直接 new 实例
- 所有遍历状态(如
currentIndex、stack、visitedSet)声明为 private final,且不提供任何 setter 或公开 getter - 禁止将容器的原始数组、节点引用、子集合等直接赋值给迭代器字段;必须做隔离(如复制索引、克隆路径节点)
集合的 iterator() 方法只返回新创建的迭代器实例
每次调用 iterator() 都应返回一个**全新、独立、状态封闭**的迭代器对象,而非复用或暴露已有实例:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 错误写法:
private final Iterator<T> cachedIter = new MyIterator(...);→ 外部强转后可能反复使用,状态混乱 - 正确写法:
public Iterator<T> iterator() { return new MyIterator(this.dataSnapshot()); } -
dataSnapshot()应返回不可变副本(如List.copyOf(items))或结构快照(如树的节点路径拷贝),不共享原始状态
禁用迭代器的 remove/set/add,并明确抛出异常
即使外部强转为具体类型,也应确保调用这些方法立即失败,不留下修改窗口:
立即学习“Java免费学习笔记(深入)”;
-
remove()方法体直接抛UnsupportedOperationException("Not supported for safety") - 不要留空实现或静默忽略——这会让强转后的误用难以被发现
- 若需支持删除,应在容器层面提供原子方法(如
removeIf(Predicate)),而非交由迭代器操作底层结构
不返回任何可被强转利用的可变中间对象
避免在迭代逻辑中暴露可被截获和篡改的中间容器(如临时 List、Map、数组):
- 不要在
next()中返回new ArrayList<>(innerList)后再缓存该 list 引用——外部强转后仍可 clear() - 对返回元素是可变对象(如
Person)的情况,next()应返回深拷贝:return currentPerson.copy(); - 禁止返回
Arrays.asList(...)、Collections.synchronizedList(...)等伪不可变包装,它们底层仍可被修改

















