String对象在Java的堆和常量池中的情况

本文详细解析了 Java 中 String 类的不同实例化方式及其比较运算的结果,包括直接赋值与 new 关键字创建的区别,以及 intern 方法的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

String(jdk1.7)

1.非new出来的String

如果不是new出来的String,如果两个值相等那么返回true:

String s = "1";
String s1 = "1";
System.out.println(s == s1);

这样返回的值是true:
非new的String
可以看出在定义变量s之后只是在常量池中创建值为“1”的常量,当定义s1时会去常量池中查是否存在值为“1”的常量,此时1在定义s的时候已存在,两者引用地址指向常量池的“1”所以s==s1返回为true。

2.new出来的String

如果是new出来的String那就要视情况来定:

1).两个都是new出来的:

String s = new String("1");
String s1 = new String("1");
System.out.println(s == s1);

这样返回的是false:
String全都是new出来的
在定义s的时候s是new出来的,此时虚拟机会在堆中新建一个s的引用对象并在常量池中存放值为“1”的常量,s1同理,在判断s==s1的时候是判断的两者的引用地址而不是值,因为s和s1在堆中分别new了一个引用地址,所以s==s1为false。

2).其中一个String是new的一个非new的

String s = "1";
String s1 = new String("1");
System.out.println(s == s1);

此时返回的也是false:
一个是new一个是非new
s是非new的所以不会在堆中创建引用,s1会在堆中创建引用,所以s指向常量池中的地址,s1指向堆中的地址,所以s==s1为false,反过来先new s再定义非new s1也是一样的。

3).加入.intern()方法

intern()方法的目的是当执行此方法的时候会在常量池创建此String的值,当另一个String定义的时候可以节省内存。

String s = new String("1");
s.intern();
String s1 = "1";
System.out.println(s == s1);

此时返回的是false:
intern
定义s的时候会在堆中建s的应用并在常量池中新建 值为“1”的常量,所以此时执行s.intern();其实是没有起作用的,当s1定义的时候指向常量池中的“1”,所以s的地址是堆中的s1是常量池,所以两者的引用地址不同。

4).特别说明的是这种情况

String s = new String("11") + new String("11");
s.intern();
String s1 = "1111";
System.out.println(s == s1);

此时返回的是true:
为true
当定义s的时候是在堆中建立一个值为“1111”的引用而在常量池中新建的是“11”的常量,在执行intern()方法后在jdk1.7中为了节省内存像s这种定义在常量池中存的是s在堆中的引用地址值为“1111”的常量,所以当s1定义后去常量池中找到“1111”的时候地址是s的引用地址,所以s==s1为true,因为两者的引用地址是相同的。
所以在进行String的判断时要使用.equals()方法哟

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值