前言:

本文讨论string 对象分别在字符串常量及堆中的比较

String(jdk1.7)

1.非new出来的String

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

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

这样返回的值是true:

可以看出在定义变量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:

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

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

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

此时返回的也是false:

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:

定义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:

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

所以在进行String的判断时要使用.equals()方法哟

转载自
原文:https://blog.csdn.net/jiavelff/article/details/79148018?utm_source=copy