ICU 79 升级笔记:C++ 类标 final、H24 弃用,78.3 到 79 的验证排期
谁会受影响
- 编译 ICU4C 的:需要 C++17(已测到 C++23),Windows 最低 Win7。
- 直接用 ICU4J 的:从 ICU 78 起最低 Java 版本由 8 提到 11(ICU-23072),当前支持 Java 11..25;Android API 21+ 可能要做 library desugaring。
- 继承过 ICU C++ 类的:ICU 79 计划把长期标注「不适合被继承」的类(例如
UnicodeString)声明为final,现有子类会直接编译失败(ICU-23284)。 - 用了 H24 小时制、week-of-year、pre-Meiji 日本年号的:输出会变(CLDR-18303 / CLDR-18275 / CLDR-11400、ICU-23341)。
- 依赖 ICU4J Java 序列化的:从 ICU 80 起不再保证跨版本兼容(ICU-23484)。
- 用了 UnicodeSet pattern 冷门写法的:边角用例的解析结果会变(UTS #61、ICU-23509)。
具体变更
版本现状
ICU 78.3 是维护版,2026-03-17 发布,主要更新 CLDR 48.2,另修一个 C++ code point iterator bug,tzdata 2026a(ICU-23330)。Maven 坐标 com.ibm.icu:icu4j:78.3。维护版不动 API,下一大版本就是 79。
ICU 79 RC 于 2026-09-25 发布,正式版预计 2026 年 10 月底。下载 tag:release-79.1rc,文档见 ICU 79 download。初始发布库版本 79.1,后续维护版是 79.2、79.3。
79 的内容面:升级 Unicode 18,新增两个大型历史文字 (Small) Seal 与 Jurchen,新货币符号 RUFIYAA、UAE DIRHAM、OMANI RIAL,9 个新 emoji,line & grapheme cluster breaking 分段改进;升级 CLDR 49 locale 数据。
平台门槛
ICU4C 需要 C++17,已测到 C++23;Windows 最低 Windows 7。
ICU4J 最低 Java 11,支持 Java 11..25(至少);Android API 21+ 可能需 library desugaring。
ICU 79 计划中的破坏性变更
- C++ 类标 final:CLDR 与 ICU 计划把长期文档注明「不适合被继承」的 C++ 类(例如
UnicodeString)声明为final。这些 API 早于 C++ 的final关键字,改动的目的是让 API 更稳健,代价是破坏那些建立了不受支持子类的用户。见 ICU-23284。 - 弃用 H24:不常见的 H24 小时循环被弃用,行为改成与 H23 一致(CLDR-18303)。
- week-of-year 一律 ISO:周编号统一遵循 ISO 规则(CLDR-18275)。
- ICU4J 序列化:ICU-TC 同意从 ICU 80 起逐步取消 ICU4J 的跨版本 Java 序列化兼容保证。理由是 Java 默认序列化机制带来大量维护开销、限制内部类重构与演进,并有已知安全风险。详见 ICU-23484。
CLDR advanced warnings 里还有更多待办项。
已经发生的行为变化
- UnicodeSet pattern:为配合 Draft UTS #61(Unicode Set Notation)标准化,ICU 中 UnicodeSet pattern 解析有多处变更,某些边角用例会改变原本可接受的 pattern 的行为(详见 User Guide 的 UnicodeSet 章节)。同时支持新语法:更可读的转义
\N{20AC:EURO SIGN}与\N{20AC:€:EURO SIGN},更可读的 not-property-value 表达式[:Property≠Value:]与\p{Property≠Value}(ICU-23509)。 - 序数日期:支持序数日期格式化(如 December 25th)以及非纯数字的日期(CLDR-7408 & ICU-23364)。
- pre-Meiji 日本年号移除:因数据不确定性被移除,明治前日期惯例使用公历(CLDR-11400、ICU-23341、ICU-23108)。
- 78 的背景一句:ICU 78 于 2025-10-30 发布,升级 Unicode 17 + CLDR 48;其中 Locale 类优化后常见 locale ID 的对象只占 40 字节(原来至少 224 字节,ICU-20392),ICU4J 新增 Segmenter API 替代 BreakIterator。
性能
行断行(line break)的反向迭代不再需要计算从字符串开头到迭代起点之间的所有断点(ICU-23478)——这个回归从 ICU 62 起就存在。79 另有大量 bug 修复,以及性能、堆内存、多线程、OOM 处理方面的改进。
构建与运维
- ICU data 裁剪:ICU4J 从 ICU4C 移植了数据文件加载的 tracing,可用来查明需要哪些数据文件,从而精简 ICU 数据(ICU-20656)。
- lifetimebound:ICU4C common 库的公开 API 按需标注了
U_LIFETIME_BOUND,有助于提前发现对象生命周期错误(ICU-23310);代价是编译告警可能变多。 - ICU4J LinkUtilities:新增类,实现 UTS #58(Unicode Link Detection and Formatting: URLs and Email Addresses)(ICU-23431)。
- MessageFormat 2.0:C++ 与 Java 的 CLDR MessageFormat 2.0 实现更新到 CLDR 49,部分 API 仍是 technology preview。
tzdata 与 CLDR
tzdata 2026d(2026-09)。CLDR 49 与 ICU 79 一同发布,新增 3 个单位:milliinch(US mil)、poundal、syne。Unicode 18.0.0 于 2026-09-16 发布;ICU4X 2.3 于 2026-08-14 发布,是独立仓库的 Rust 实现,不在这次升级路径上。
怎么验证与应对:92 天窗口里的排期
- 先跑 78.3。维护版不动 API,只带 CLDR 48.2 与 tzdata 2026a,适合当基线。Java 侧把依赖换成
com.ibm.icu:icu4j:78.3,回归结果作为对照。 - 把 79 RC 放进测试环境,用同一批用例比结果,重点看 collation 排序、日期时间格式(H23/H24、序数日期、日本年号)、week-of-year、UnicodeSet pattern 解析这几块。
- 编译侧:确认构建链支持 C++17;如果开了
-Werror,U_LIFETIME_BOUND带来的新告警要么修,要么按需关掉。ICU4J 侧检查 Android desugaring 配置。 - 继承侧:把自建的
UnicodeString等子类改成组合或内部包装,赶在 79 正式版前验证通过。 - 持久化侧:ICU 80 起不再保证跨版本 Java 序列化兼容,别把 ICU4J 对象当作持久化格式写盘。