tochararray() 总是返回新分配的char[],与原string内部存储无关;java 9+需解码byte[]再复制,有拷贝开销;修改返回数组不影响原字符串,因string不可变。

String.toCharArray() 会创建新数组还是复用原字符串内部存储?
它总是返回一个新分配的 char[],和原 String 内部的 value 数组无关。Java 9+ 中 String 底层改用 byte[] + 编码标识,toCharArray() 会先解码再复制成 char[],所以必然有拷贝开销。
这意味着:修改返回的数组不会影响原字符串(这是好事),但高频调用可能触发额外 GC —— 如果只是读取、不修改,考虑直接用 String.charAt(i) 配合循环更轻量。
为什么对空字符串或 null 调用 toCharArray() 会出问题?
null 时直接调用会抛 NullPointerException;空字符串 "" 则安全返回长度为 0 的 char[]。
常见错误写法:
String s = null; char[] arr = s.toCharArray(); // 运行时报错
安全做法:
- 先判空:
if (s != null) { char[] arr = s.toCharArray(); ... } - 或用
Objects.requireNonNull(s).toCharArray()明确失败语义 - 工具类如 Apache Commons Lang 的
StringUtils.toCharArray(s)对null返回null,需额外判空
toCharArray() 后修改数组内容,会影响原字符串吗?
完全不会。字符串在 Java 中是不可变的(immutable),toCharArray() 返回的是副本,无论你怎么改这个数组,原 String 对象的内容、哈希值、内存地址都保持不变。
典型误用场景:
String s = "hello"; char[] arr = s.toCharArray(); arr[0] = 'H'; System.out.println(s); // 输出仍是 "hello",不是 "Hello"
如果目标是生成新字符串,得手动构造:new String(arr) 或 String.valueOf(arr)。
替代方案:什么情况下不该用 toCharArray()?
当只需顺序遍历且不修改字符时,toCharArray() 是冗余的。JVM 对 charAt() 有优化,且避免了数组分配。
适用 toCharArray() 的真实场景:
- 需要排序(如
Arrays.sort(arr)) - 需要原地修改(如大小写翻转、替换特定位置字符)
- 要传给只接受
char[]的 API(如某些加密、编码方法) - 频繁随机访问 + 多次使用,缓存数组比反复调用
charAt()更快(但需权衡内存)
Unicode 补充字符(如 emoji)要注意:toCharArray() 拆出的是 UTF-16 编码单元,一个 emoji 可能占两个 char(代理对)。如果按“字符”逻辑处理,得用 String.codePoints() 流式迭代,而不是依赖数组下标。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











