应避免触发UnsupportedEncodingException,优先使用StandardCharsets常量;必须用字符串编码名时,先调用Charset.isSupported校验,再安全处理。

UnsupportedEncodingException 是 Java 中的检查型异常(checked exception),当指定的字符编码名称不被 JVM 支持时抛出,常见于 String.getBytes(String charsetName) 或 new String(byte[], String charsetName) 等调用中。
为什么不能用常规 try-catch 忽略它?
因为它是检查异常,编译器强制你处理:要么捕获,要么声明抛出。但硬编码非法编码名(如 "UTF-8X")在开发阶段就该暴露问题,而非等到运行时——所以**根本策略是避免触发它**,而不是“兜底捕获”。
推荐做法:用标准 Charset 静态常量代替字符串
从 Java 7 开始,java.nio.charset.StandardCharsets 提供了预定义、JVM 必须支持的常量(如 StandardCharsets.UTF_8),完全绕过字符串编码名解析,也就不会抛 UnsupportedEncodingException:
- ✅ 替换
str.getBytes("UTF-8")→str.getBytes(StandardCharsets.UTF_8) - ✅ 替换
new String(bytes, "GBK")→new String(bytes, StandardCharsets.GBK)(注意:GBK 是 Java 7+ 可选标准,部分精简 JVM 可能不包含;若需兼容旧环境,见下条) - ✅ 所有
Charset.forName("xxx")调用也应优先用StandardCharsets.xxx
必须用字符串编码名时:提前校验 + 明确异常处理
例如配置文件读取编码名、用户输入等不可控场景:
- 先用
Charset.isSupported(encodingName)判断是否可用,返回false时走默认逻辑(如 fallback 到 UTF-8)或报错提示 - 若仍需调用字符串 API,用 try-catch 捕获并转换为更明确的业务异常:
String encoding = config.getEncoding(); // 来自外部
if (!Charset.isSupported(encoding)) {
throw new IllegalArgumentException("Unsupported encoding: " + encoding);
}
try {
byte[] data = str.getBytes(encoding);
} catch (UnsupportedEncodingException e) {
// 实际上上面已校验,此处可作为防御性兜底
throw new IllegalStateException("Unexpected encoding error", e);
}
兼容老版本 JDK(Java 6 及以下)的替代方案
若无法升级 JDK,可用 Charset.availableCharsets() 获取支持列表做白名单校验,或封装工具方法统一处理:
- 定义常用编码白名单(如
Arrays.asList("UTF-8", "GBK", "ISO-8859-1")) - 校验输入编码是否在名单内,不在则拒绝或 fallback
- 避免直接把用户输入/配置值传给
String构造函数或getBytes
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











