UnsupportedOperationException 是设计意图的明确表达,用于接口适配器模式和不可变集合中主动拒绝非法操作,强化契约、防止误用,而非表示错误。

UnsupportedOperationException 的出现,往往不是错误,而是设计意图的明确表达——它在接口适配器模式和不可变集合中,被用作一种“声明式限制”,主动拒绝不被允许的操作,从而强化契约、防止误用。
在不可变集合中:用异常代替方法存在
Java 9+ 的 List.of()、Set.of()、Map.of() 返回的是专用不可变实现(如 ImmutableCollections.List12),它们压根不提供 add、remove、set 等方法的签名。当你写 list.add("x"),编译能过(因继承自 List 接口),但运行时立即抛出 UnsupportedOperationException。这不是补丁,是设计闭环:
- 它比
Collections.unmodifiableList()更彻底——后者只是包装器,原始列表一改,视图就变;而List.of()是全新构造、完全隔离的数据结构 - null 元素或重复 key 会在构造时就抛
NullPointerException或IllegalArgumentException,异常前置,不留给运行时猜测空间 - 大小限制(如 Map.of 最多 10 对)也是契约一部分,超限时必须显式切换到
Map.ofEntries()或copyOf(),迫使开发者面对设计权衡
在接口适配器模式中:用异常标注“未实现”语义
适配器模式常用于复用已有类以满足新接口。当目标接口定义了多个方法,但源类只支持其中一部分时,适配器可对暂不支持的方法直接抛 UnsupportedOperationException:
- 例如,一个只读文件系统适配器实现了
FileReader接口,但对write()方法不做任何转发,而是抛该异常,清晰传达“此实现不支持写入”的语义 - 这比返回 null、静默忽略或抛更模糊的
RuntimeException更具可读性,调用方能立刻理解这是功能边界,而非临时 bug - 在 Java NIO 的
ReadOnlyBuffer类中,put()系列方法全部抛此异常,与底层缓冲区的只读属性严格对齐
为什么不用编译期禁止?
接口本身无法约束实现类是否提供具体行为;抽象类可设 abstract 方法,但无法表达“这个方法存在,但永远不该被调用”。UnsupportedOperationException 填补了这一空白:
- 它让接口契约在运行时可验证,尤其适用于“部分实现”或“安全冻结”场景
- 工具链(如 IDE、静态分析器)可识别该异常模式,给出警告或建议替代路径
- 测试中容易覆盖——断言某操作是否如预期抛出该异常,本身就是关键用例验证
实际使用建议
如果你自己设计 API:
- 对明确不支持的操作,优先抛 UnsupportedOperationException,而不是吞掉、返回默认值或抛通用异常
- 在 Javadoc 中说明为何不支持,必要时推荐替代方案(如“请使用
copyOf()替代of()处理大集合”) - 避免在高频读路径上滥用——异常有开销,但它本就不该出现在正常流程中










