StringBuilder的subSequence方法不能实现零拷贝,它返回新创建的String对象,底层调用String(char[], int, int)构造器复制字符数组。

Java 的 StringBuilder 的 subSequence(int start, int end) 方法**不能实现零拷贝**,它返回的是一个**新创建的 String 对象**,底层会复制对应范围的字符数组内容。
subSequence 实际行为:复制而非视图
subSequence 是继承自 CharSequence 接口的方法。在 StringBuilder 中,它的实现等价于:
return new String(value, start, end - start);
其中 value 是内部的 char[] 数组。注意:这里调用了 String(char[], int, int) 构造器 —— 在 Java 7u6 之后,该构造器**一定会进行数组复制**(早期版本曾共享数组,但因安全与内存泄漏问题被废弃)。所以每次调用都产生新字符串,涉及内存分配和字符拷贝。
立即学习“Java免费学习笔记(深入)”;
为什么不存在“字符视图”?
-
StringBuilder本身不提供类似ByteBuffer.slice()或Arrays.asList().subList()那样的轻量级视图接口; - Java 的
String是不可变且自有字符副本的,设计上就排除了共享底层数组的可能; - 即使你用反射绕过访问限制,也无法安全复用
StringBuilder内部的char[]构造无拷贝视图——因为该数组可被后续append/delete等操作修改,破坏视图一致性。
替代思路:按需选择更合适的方案
如果你追求避免不必要的字符串拷贝,可考虑以下方式:
-
延迟转换:只在真正需要字符串时才调用
subSequence或substring,中间过程用索引(start/end)或StringBuilder自身操作(如delete(0, start)+setLength(end - start))来“逻辑截取”; -
用 CharSequence 引用原始对象:若下游 API 接受
CharSequence(如String.valueOf()、正则Pattern.matcher()),可直接传入StringBuilder本身,无需截取; -
自定义只读 CharSequence 实现(高级):封装
StringBuilder引用 + 范围,重写charAt/length/subSequence,但注意这仍是逻辑视图,subSequence返回时仍需新建String; -
切换到 MutableString 类库(如 Apache Commons Text 的
StrBuilder或自研结构):部分第三方实现支持更灵活的切片策略,但标准 JDK 无此能力。
小结
StringBuilder.subSequence 简洁易用,但不是零拷贝操作。它本质是便捷的“截取并转字符串”工具。真有高性能文本处理需求(如解析器、流式处理),应减少中间字符串生成,多用索引、预分配容量、复用对象,或引入专为高效字符处理设计的数据结构。


















