JDK 17 升级到 JDK 21 的变更汇总
JDK 17 到 JDK 21 跨越了 JDK 18、19、20 三个非 LTS 版本。本文汇总这四个版本引入的重要变更,重点关注 breaking change 和需要主动迁移的部分。 JDK 18(2022 年 3 月) Breaking Change UTF-8 成为默认字符集(JEP 400) 这是 17 → 21 迁移中最常见的隐性 breaking change。JDK 18 起,Charset.defaultCharset() 固定返回 UTF-8,不再跟随操作系统区域设置。 受影响的场景: new String(bytes) — 未指定编码,依赖平台默认值 new FileReader(file) — 未指定编码 System.out.println() 输出非 ASCII 字符 读写文件时未显式指定编码 对 Linux 生产环境的实际影响 大多数现代 Linux 发行版默认 locale 是 en_US.UTF-8 或 zh_CN.UTF-8,JDK 17 在这类环境下默认字符集本来就是 UTF-8,因此 JDK 18 的这一变更对标准 Linux 服务器基本无感。 真正有风险的场景: Windows 开发/测试环境 — Windows 默认编码是 GBK/CP936,本地测试通过但部署到 Linux 后行为不同 精简容器镜像 — 某些极简 Docker 镜像不设置 locale,LANG 为空,JDK 17 此时默认字符集可能是 US-ASCII,升级到 JDK 18 后反而统一成了 UTF-8 遗留系统 — 有意依赖 GBK 平台编码处理中文数据(如读老数据库导出文件)的项目会出问题 修复方式:所有涉及字节/字符转换的地方显式指定 StandardCharsets.UTF_8。 ...