Strings与new String()的区别

在 Java 中,String str = "abc" 和 String str = new String("abc") 两种写法看似相似,实则在内存存储对象创建上有本质区别,核心差异在于是否会触发常量池的使用。

1. 字符串常量池(String Pool):理解的关键

Java 为了优化字符串操作,在内存中开辟了一块特殊区域 ——字符串常量池(位于方法区),用于存储唯一的字符串字面量

  • 当出现相同的字符串字面量时,常量池中只会保存一份,避免重复创建,节省内存。

2. 两种写法的区别

(1)String str = "abc"(字面量赋值)
  • 创建过程
    JVM 会先检查字符串常量池中是否存在 "abc":
    • 如果存在,直接让 str 引用常量池中的这个字符串对象;
    • 如果不存在,先在常量池中创建 "abc" 对象,再让 str 引用它。
  • 内存情况:只在常量池中可能创建一个对象(若之前没有),不会在堆中创建新对象。
String s1 = "abc";
String s2 = "abc";
// s1 和 s2 引用的是常量池中同一个对象,所以地址相同
System.out.println(s1 == s2); // 输出 true(== 比较的是对象地址)
(2)String str = new String("abc")(new 关键字创建)
  • 创建过程
    无论常量池中是否存在 "abc",都会在堆内存中创建一个新的字符串对象,并且这个对象的值会引用常量池中的 "abc"(如果常量池中没有,会先在常量池创建 "abc")。
  • 内存情况:至少在堆中创建一个新对象,可能在常量池创建一个对象(若之前没有)。
String s3 = new String("abc");
String s4 = new String("abc");
// s3 和 s4 是堆中两个不同的对象,地址不同
System.out.println(s3 == s4); // 输出 false
// 堆中对象的值引用常量池,所以内容相同
System.out.println(s3.equals(s4)); // 输出 true(equals 比较字符串内容)

3. 本质区别总结

写法对象创建位置常量池使用情况内存效率
String s = "abc"仅常量池(最多 1 个)优先复用常量池已有对象高(复用机制)
String s = new String("abc")堆内存(至少 1 个)可能触发常量池创建(若不存在)低(新对象)

4. 什么时候用哪种方式?

  • 优先用字面量赋值"abc"):大多数场景下,不需要在堆中创建新对象,利用常量池的复用机制,节省内存,效率更高。
  • 必要时用 new String():仅当需要在堆中创建一个全新的字符串对象(与常量池中的对象完全独立)时使用(实际开发中极少用到,除非特殊需求)。

一句话概括

"abc" 是 “复用优先”,尽量用常量池中的同一个对象;new String("abc") 是 “强制新建”,一定会在堆中产生新对象,两者的内存地址不同。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值