You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Java String类保留无参及String参数构造方法?

Java String(String)构造方法的常见疑问解答

1. 会不会造成内存浪费?

先看该构造方法的实现:

@IntrinsicCandidate
public String(String original) {
    this.value = original.value;
    this.coder = original.coder;
    this.hash = original.hash;
}

这个构造方法并没有复制原字符串的字符数组,只是引用了原对象的value、coder、hash字段,堆中新建的String对象只是一个"空壳",真正的字符数据是和原对象共享的。

如果用new String("字面量")的方式调用,确实会产生两个String对象:常量池里的字面量对象,以及堆里的新对象。但内存浪费程度很小——只是多了一个String对象的内存开销(几个字段,约几十字节),而非复制整个字符数组。不过这种场景下,堆里的新对象完全多余,直接使用常量池的对象即可。

2. 为什么注释说没必要使用这个构造方法?

源码注释提到:

Initializes a newly created {@code String} object so that it represents
the same sequence of characters as the argument; in other words, the
newly created string is a copy of the argument string. Unless an
explicit copy of {@code original} is needed, use of this constructor is
unnecessary since Strings are immutable.

核心原因是String是不可变的:一旦创建,String的内容就无法修改。既然原字符串和新字符串内容完全一致且都不可变,直接使用原对象就足够,新建对象没有实际意义,只会额外占用少量内存。

3. 为什么要保留这些"不必要"的构造方法?

主要有两个原因:

  • 历史向后兼容:这些构造方法从Java早期版本(JDK 1.0)就存在,大量老代码可能依赖它们。如果移除,会导致老项目编译失败或运行报错,破坏兼容性。
  • 极端场景的遗留需求:在早期JDK版本中,String的value字符数组并非private final,存在被外部修改的风险,此时String(String)构造方法可用来复制数组,保证新对象的独立性。虽然现在value已经是不可变的,但为了兼容历史场景,仍保留该方法。

至于无参构造String(),它会创建一个空String对象,同样可以用常量池的""代替,保留它也是出于向后兼容的考虑。

内容的提问来源于stack exchange,提问作者kuruthi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 23:20:06