找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

1333

积分

0

好友

177

主题
发表于 5 小时前 | 查看: 2| 回复: 0

String s = new String("abc") 这条语句创建的对象数量,可能是1个,也可能是2个。

核心关键在于:字符串常量池中是否已经存在字面量“abc”对应的对象。

当JVM编译期遇到字符串字面量 "abc" 时,会将其视作一个编译期常量,并尝试将其放入字符串常量池。具体过程如下:

  1. 检查池中是否存在:首先检查字符串常量池中是否已存在内容为“abc”的String对象。
  2. 决定是否创建
    • 如果不存在,JVM会在常量池中创建一个新的String对象来代表这个字面量。
    • 如果已存在,则直接引用池中已有的对象。

new String("abc")中的new关键字,则必定会在Java堆(Heap)上显式地创建一个新的、独立的String对象,无论常量池中情况如何。

因此,该语句创建的对象总数分为以下两种情况:

情况一:常量池中原来没有“abc”
此时会创建 2个 String对象。

  1. 一个在字符串常量池中,由字面量"abc"触发创建。
  2. 一个在堆(Heap) 上,由new关键字创建。

情况二:常量池中原来已有“abc”
此时只会创建 1个 String对象。

  1. 仅在堆(Heap) 上创建新对象,常量池中的已有对象被直接引用。

为了更直观地理解,我们可以通过一个代码示例来验证:

public class StringCreationExample {
    public static void main(String[] args) {
        // 此行代码会确保“abc”存在于字符串常量池中
        String s1 = "abc";

        // 使用new关键字在堆上创建一个新的String对象
        String s2 = new String("abc");

        System.out.println(s1 == s2); // 输出 false
        System.out.println(s1.equals(s2)); // 输出 true
    }
}

输出结果:

false
true

结果分析:

  • s1 引用的是字符串常量池中的 "abc" 对象。
  • s2 引用的是通过 new String("abc") 在堆上创建的全新对象。
  • 虽然两个对象存储的字符串值相同(equals()比较为true),但它们是两个完全不同的对象,内存地址不同,因此 s1 == s2 比较引用时结果为 false

理解这一过程有助于深入理解String类和字符串常量池的机制,这是掌握Java虚拟机(JVM)内存模型的重要基础。简而言之,new String("abc")创建的对象数量取决于常量池的初始状态,可能是1个(仅堆对象),也可能是2个(堆对象+常量池对象)。




上一篇:Python手把手实现RAG知识库:基于Qwen2.5-0.5B模型与LangChain的Mac端低成本实践
下一篇:高并发系统性能核心:TPS、QPS与并发数详解及关系解析
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-24 12:41 , Processed in 0.272639 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表