string.length()返回char数组长度而非unicode码点数,如"?"返回2;需用codepointcount()或codepoints().count()获取用户感知字符数;null需显式判空,length()本身是o(1)操作。

length() 方法返回的是 Unicode 码点数量,不是 char 数量
Java 的 String.length() 返回的是字符串内部 char 数组的长度,而一个 Unicode 字符(比如 emoji 或中文生僻字)可能占两个 char(即代理对)。这意味着遇到 ?、??、? 这类字符时,length() 会返回 2 而不是 1。
如果你真正需要“用户感知的字符数”,得用 String.codePointCount(0, str.length())。
- ✅ 正确统计 emoji 或增补平面字符:用
str.codePointCount(0, str.length()) - ⚠️ 错误假设:
"??".length()返回 2,但人眼只看到 1 个图标 - ? 替代方案:Java 9+ 可用
str.codePoints().count()(流式,稍慢)
空字符串和 null 的处理必须显式判断
length() 本身不抛 NullPointerException,但调用它之前如果对象是 null,就会在点号处直接崩溃。空字符串 "" 是合法对象,.length() 返回 0 —— 这没问题,但很多人混淆了 null 和空串。
- ❌ 危险写法:
str.length() > 0(若str == null,运行时报NullPointerException) - ✅ 安全写法:
str != null && str.length() > 0,或更推荐Objects.nonNull(str) && !str.isEmpty() - ? 注意:
isEmpty()是 Java 6+ 引入的语义等价于length() == 0,但可读性更好
性能上 length() 是 O(1),但别误以为它“计算”了长度
String 在 Java 中是不可变对象,其内部 value 字节数组和 count(或 Java 9+ 的 coder+value 长度)在构造时就已确定。length() 只是返回一个字段值,没有遍历、没有编码解析。
- ✅ 可放心在循环条件里用:
for (int i = 0; i 不会造成性能问题 - ❌ 不要为“优化”提前存变量(如
int len = s.length()),除非你在高频热点路径且 JIT 未内联(极罕见) - ⚠️ 混淆点:
StringBuilder.length()同样是 O(1),但它的capacity()才反映底层数组大小
不同 JDK 版本下 length() 的底层含义略有差异
Java 8 及以前,String 内部用 char[] value,length() 就是该数组长度;Java 9 引入紧凑字符串(compact strings),内部改用 byte[] value + byte coder(标识 Latin-1 或 UTF-16),但 length() 行为完全兼容 —— 它仍返回逻辑字符数(即 UTF-16 编码单元数),不是字节数。
- ✅ 你不需要关心底层是 char 还是 byte 数组,API 行为一致
- ⚠️ 但如果你用反射读
value字段或调用getChars(),JDK 9+ 的 byte 数组可能让你误算字节长度 - ? 查看真实字节数:用
str.getBytes(StandardCharsets.UTF_8).length,这和length()完全不是一回事
length() 的“表象正确”可能掩盖深层逻辑缺陷。










