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

Java JVM是否会像复用String一样复用自定义类的相同不可变实例?

首先我们先明确:JVM针对String的重复实例复用(也就是字符串驻留、常量池机制)是专门为这个核心基础类做的定制化优化,默认不会对自定义类做类似的自动实例复用处理,针对你提出的三个问题具体解答如下:

首先给出你提到的类代码参考:

final public class ImmutReuseTest {

    final public int num;
    final public SomeImmutableThing thing;

    public ImmutReuseTest(final int num, final SomeImmutableThing thing) {
        this.num = num;
        this.thing = thing;
    }

}

final public class SomeImmutableThing {

    final public int nomm;
    final public String text;

    public SomeImmutableThing(final int nomm, final String text) {
        this.nomm = nomm;
        this.text = text;
    }

}
  • 问题1答案:不会
    String的实例复用依赖专门的字符串常量池逻辑,普通自定义不可变类没有这套默认自动去重机制。只要你主动调用构造方法创建新实例,哪怕所有字段的取值完全相等,JVM也会为每个new操作分配独立的堆内存,不会自动复用已有同值实例。如果需要复用你得自己手动实现享元模式,通过缓存池来管理实例的创建和返回。
  • 问题2答案:不会
    哪怕所有ImmutReuseTest实例内部的SomeImmutableThing字段都指向同一个实例,JVM也不会自动对ImmutReuseTest本身做实例复用。唯一可能和“消除重复创建”沾边的优化是JIT的逃逸分析标量替换:如果某个ImmutReuseTest实例的作用域完全没逃出当前方法,JIT可能会直接把实例拆解成独立的字段放到栈上存储,完全跳过堆上的对象创建流程,这不属于实例复用,是直接消除了对象创建。
  • 问题3答案:不会
    不管类是严格不可变还是有效final,JVM都不会默认对自定义类做自动实例复用。尤其是类内部存在可变字段的场景,哪怕你实际上不会修改这些字段,JVM也不可能主动做复用——万一后续字段被修改,复用实例会直接导致逻辑错误,风险完全不可控。这类场景下的复用只能由开发者自己保证实例的不可变性,手动实现缓存逻辑来完成。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 05:12:01