UnmappableCharacterException 是非受检运行时异常,继承自 CharacterCodingException;在 CharsetEncoder 编码时遇字符无映射且策略为 REPORT 时抛出,如 ISO-8859-1 编码中文。

UnmappableCharacterException 是 Java 中 java.nio.charset 包下的一个运行时异常(RuntimeException),不是受检异常(checked exception)。这点需要特别澄清——它不会强制要求你用 try-catch 捕获或 throws 声明。
为什么它不是受检异常?
Java 的异常体系中,只有继承自 Exception 但不继承自 RuntimeException 的类才是受检异常。而 UnmappableCharacterException 直接继承自 CharacterCodingException,后者是 RuntimeException 的子类:
Throwable- └──
Exception - └──
IOException(受检) - └──
RuntimeException(非受检) - └──
CharacterCodingException - └──
UnmappableCharacterException✅
它在什么场景下抛出?
当使用 CharsetEncoder 将字符序列编码为字节时,遇到某个字符在目标字符集中没有对应编码映射,且编码器的 编码策略(CodingErrorAction)设置为 REPORT,就会抛出该异常。
常见例子:
立即学习“Java免费学习笔记(深入)”;
- 用
GBK编码器处理含 emoji(如 ?)的字符串(GBK 不支持 emoji) - 用
ISO-8859-1编码含中文的字符串(该字符集只支持西欧字符) - 手动调用
encoder.encode(charBuffer, byteBuffer, true)且未预先配置容错策略
如何正确处理它?
虽然不是受检异常,但生产代码中建议主动应对,避免程序崩溃:
-
提前设置容错策略:调用
encoder.onUnmappableCharacter(CodingErrorAction.REPLACE)或.IGNORE,而非默认的REPORT - 捕获并记录:即使非受检,也可用 try-catch 捕获,打印问题字符和位置,便于排查数据源问题
-
选用更宽泛的字符集:如优先用
UTF-8替代GBK或ISO-8859-1,大幅降低映射失败概率 - 验证输入字符范围:对严格受限的协议场景(如某些金融报文),可在编码前过滤或校验非法字符
一个小验证示例
以下代码会触发 UnmappableCharacterException(注意:需显式设为 REPORT 才抛):
encoder.onUnmappableCharacter(CodingErrorAction.REPORT); // 关键
encoder.encode(CharBuffer.wrap("你好")); // 抛出 UnmappableCharacterException
去掉 onUnmappableCharacter(...) 或改为 REPLACE,就不会抛异常。


















