CharacterCodingException 是 Java NIO 中字符编解码错误的抽象基类,不可直接实例化,其子类 MalformedInputException(输入格式非法)和 UnmappableCharacterException(字符不可映射)才实际抛出;捕获它可统一处理两类编码异常,适用于 CharsetDecoder/Encoder 的 decode/encode 场景,但优先推荐通过设置 onMalformedInput() 和 onUnmappableCharacter() 策略主动规避异常。

CharacterCodingException 是 Java 中与字符编码/解码过程失败相关的抽象异常,它本身不能被直接抛出,而是作为 MalformedInputException 和 UnmappableCharacterException 的父类存在。捕获它,本质上是统一处理底层编解码器(如 CharsetEncoder / CharsetDecoder)在读写字符流时遇到的非法输入或不可映射字符问题。
捕获 CharacterCodingException 的实际意义
由于 CharacterCodingException 是抽象类,代码中不会 new 它,也不会被 JVM 直接 throw。真正抛出的是它的两个子类:
- MalformedInputException:输入字节序列不符合指定字符集的编码规则(例如 UTF-8 中出现孤立的 continuation byte)
- UnmappableCharacterException:输入字符无法映射到目标字节序列(例如用 ISO-8859-1 编码中文字符)
因此,捕获 CharacterCodingException 就相当于同时捕获这两类底层错误,适合做统一的编码容错处理,比如记录日志、降级使用替代字符、或切换编码尝试重试。
典型触发场景和捕获方式
该异常主要出现在基于 NIO 的字符编解码操作中,例如:
立即学习“Java免费学习笔记(深入)”;
- 通过
CharsetEncoder.encode()将 CharBuffer 转为 ByteBuffer 时 - 通过
CharsetDecoder.decode()将 ByteBuffer 转为 CharBuffer 时 - 使用
InputStreamReader或OutputStreamWriter且底层涉及自定义编码器时
捕获示例:
Charset utf8 = StandardCharsets.UTF_8;
CharsetDecoder decoder = utf8.newDecoder();
try {
CharBuffer result = decoder.decode(ByteBuffer.wrap(new byte[]{(byte)0xFF, (byte)0xFE})); // 非法 UTF-8 序列
} catch (CharacterCodingException e) {
if (e instanceof MalformedInputException) {
System.err.println("输入字节格式错误:" + e.getMessage());
} else if (e instanceof UnmappableCharacterException) {
System.err.println("字符无法映射:" + e.getMessage());
}
}
避免异常比捕获更重要
这类异常本质反映数据与编码不匹配,属于可预防问题。建议优先从源头控制:
- 明确输入源的编码格式(如 HTTP 响应头的 Content-Type、文件 BOM、数据库连接参数),不要依赖默认平台编码
- 使用
StandardCharsets中的常量(如 UTF_8)代替字符串名称,避免拼写错误或查不到 Charset - 对不可信输入,设置编码器的错误处理策略,例如:
decoder.onMalformedInput(CodingErrorAction.REPLACE).onUnmappableCharacter(CodingErrorAction.REPLACE) - 必要时先检测 BOM 或用工具库(如 ICU4J、juniversalchardet)自动识别编码


















