string转char[]用tochararray(),返回新数组副本;char[]转string用new string(char[]),会复制内容生成不可变字符串。二者均不共享内存,需注意null检查和'\0'处理。

String转char[]:用toCharArray()最直接,但别改它
Java里把String变成char[],就一个方法:toCharArray()。它返回的是原字符串内容的**新数组副本**,不是引用原内部字符——这点很多人误以为能“共享内存”来省空间,其实不能。
常见错误现象:
— 把返回的数组拿去修改,再期望原String变(不可能,String不可变)
— 在循环里反复调用toCharArray()处理同一字符串(小开销,但没必要)
- 使用场景:需要逐字符修改、排序、加密预处理等必须可变操作时才转
- 性能影响:每次调用都新建数组,长度为
string.length(),堆上分配,短字符串无感,长文本注意GC压力 - 兼容性:JDK 1.0起就有,全版本安全
示例:
String s = "hello"; char[] cs = s.toCharArray(); // ✅ 正确 cs[0] = 'H'; // 修改只影响cs,s还是"hello"
char[]转String:优先用String(char[])构造器
从char[]建String,首选new String(char[])。它会拷贝数组内容,生成真正不可变的String实例——这是最干净、语义最明确的方式。
容易踩的坑:
— 用String.valueOf(char[])?它底层也是调这个构造器,但多一层方法跳转,无必要
— 传入null数组?直接抛NullPointerException,不判空就崩
— 用Arrays.toString(char[])?那出来是"[h, e, l, l, o]"这种带括号逗号的字符串,不是你想要的
立即学习“Java免费学习笔记(深入)”;
- 参数差异:
String(char[])只接受非null数组;如果只想用部分区间,得用String(char[], int offset, int count) - 性能影响:同样要复制数组,时间复杂度O(n),但比拼接或
StringBuilder更轻量(无builder对象开销) - 注意:别试图复用同一个
char[]反复构造不同String来“节省内存”——String内部已做驻留优化,手动搞反而干扰JVM
示例:
char[] cs = {'h', 'e', 'l', 'l', 'o'};
String s = new String(cs); // ✅ 推荐
// String s2 = String.valueOf(cs); // ⚠️ 可用,但绕路
边界情况:空数组、null、含\0字符怎么办
实际代码里常遇到这些边缘输入,toCharArray()和String(char[])行为很明确,但容易想当然。
常见错误现象:
— 认为"".toCharArray()返回null(错,返回长度为0的空数组)
— 对null数组直接传给new String(null)(立刻NPE)
— 字符数组里有'\0',以为截断(不会,'\0'就是普通字符,照常参与构造)
-
"".toCharArray()→new char[0],可用.length判断,别== null - 构造前务必检查
char[]是否为null,尤其来自外部API或IO读取时 -
'\0'在Java字符串里合法存在,比如new String(new char[]{'a', '\0', 'b'})结果是"a\u0000b",长度为3
为什么不用StringBuilder或+拼接来“中转”
有人图省事,把char[]先塞进StringBuilder再toString(),或者用"" + cs——这完全没必要,且引入额外对象和逻辑。
典型错误写法:
— new StringBuilder().append(cs).toString():多创建builder、append逻辑、扩容判断,纯属加戏
— "" + cs:触发String.valueOf(Object),最终调cs.toString(),输出[C@xxxxx这种哈希值,根本不是内容
- 性能对比:直接
new String(cs)比StringBuilder方式快2~3倍(小数组),且堆内存更少 - 可读性:构造器意图清晰;
StringBuilder暗示后续还要追加,造成误导 - 唯一合理用
StringBuilder的场景:你要把多个char[]或混合其他字符串拼一起,而不是单次转换
null检查、误信共享引用、或用错工具链,问题往往出现在上线后数据异常时,而不是编译期。










