String.codePointAt() 用于正确获取 Unicode 码点,尤其处理增补字符(如 emoji、U+20000 等),避免 charAt() 错误拆分代理对;它返回 int 类型码点,自动合并高/低代理对,并需配合 Character.charCount() 安全遍历。

Java 中 String.codePointAt() 的作用不是“读取双字节字符变量”,而是**正确获取 Unicode 码点(code point)**,尤其在字符串含增补字符(surrogate pairs,即 Unicode 码点 ≥ 0x10000 的字符,如 emoji、部分汉字、古文字等)时,避免用 charAt() 错误拆分代理对。
理解:为什么不能只用 charAt()?
charAt() 返回的是 char 类型(16 位无符号整数),只能表示 BMP(基本多文种平面)内的字符(U+0000–U+FFFF)。而像 ?(U+1F30D)、??(由多个码点组合)、?(U+20000)这类增补字符,在 Java String 中以两个 char(高代理 + 低代理)形式存储,称为代理对(surrogate pair)。直接对代理对中任一位置调用 charAt() 会返回无效的代理值,不是真实字符。
codePointAt() 的正确用法
String.codePointAt(int index) 接收一个 char 索引,但会自动检测该位置是否为高代理(0xD800–0xDFFF),若是且后续是匹配的低代理,则合并返回完整码点;否则直接返回该位置的 char 值。它返回的是 int(可容纳全部 Unicode 码点,0–0x10FFFF)。
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 传入索引必须在
[0, string.length())范围内,越界抛StringIndexOutOfBoundsException - 若索引指向高代理(
0xD800–0xD8FF)且下一位是有效低代理(0xDC00–0xDFFF),则返回合并后的码点 - 若索引指向低代理(
0xDC00–0xDFFF)或单独的代理值,codePointAt()仍返回该char值(即无效代理码),此时需配合Character.isSurrogate()或Character.isValidCodePoint()判断
安全读取指定索引处真实字符(码点)的推荐方式
要确保“准确读取特定索引位置可能存在的双字节字符”(实为增补字符),应:
立即学习“Java免费学习笔记(深入)”;
- 先用
string.offsetByCodePoints(0, n)定位第n个码点对应的char索引(因为一个码点可能占 1 或 2 个char)——但这是反向操作 - 更常见场景是:已知
char索引i,想获取它所属的完整码点 → 直接调用string.codePointAt(i),但需跳过下一个char(如果构成代理对) - 标准做法是结合
Character.charCount(int codePoint)判断长度:
int cp = str.codePointAt(i);
i += Character.charCount(cp); // 安全推进到下一个码点起始位置
实际示例
例如字符串 "A\ud83d\udc0D"(即 "A" + ?):
-
str.charAt(0) == 'A'(正确) -
str.charAt(1) == '\ud83d'(高代理,不是独立字符) -
str.charAt(2) == '\udc0D'(低代理,不是独立字符) -
str.codePointAt(1)返回0x1F40D(? 的真实码点) -
Character.charCount(0x1F40D) == 2,说明它占两个char位置

















