#关于字符串常量池的概念想必大家都懂,今天主要围绕String对象来谈谈我的理解。
首先先给大家看一段代码
String s1="abc";
String s2=s1+"def";
String s3=s1+"def";
System.out.println(s2==s3);
让我们先来猜下这段代码的输出结果是什么?
答案既然是false!
我们都知道字符串常量池中一个字符串是唯一的,如果s2和s3指向的是字符串常量池中的字符串,那么我们的输出结果应该是true,而我们输出的结果是false,所以s2和s3并不是简单的指向字符串常量池中的数据。
我们知道String并不是基本的数据类型,它有两种创建方式:①字面量定义的方式:String str=“abc”;②new:String str=new String(“abc”);
第一种方式只是在栈空间开辟了一个空间存放str,然后在字符串常量池中存储了"abc";第二种方式则是在堆空间开辟了一个对象,在栈空间存放了一个变量str,该变量指向堆空间的对象,然后该对象指向了字符串常量池中对应的字符串,下面我们举个例子来证明一下我们的观点
class Person{
String name;
public Person(String name) {
this.name = name;
}
}
public class StringTest{
public static void main(String[] args) {
Person p1=new Person("tom");
Person p2=new Person("tom");
System.out.println(p1.name == p2.name);
}
}
由此验证了我们的观点。
回到我们最初的话题,既然我们的输出结果为false,s2和s3指向的肯定不是同一个地址,有的同学就会问了,它们指向的不都是s1+"def"这个字符串吗,事实并非如此。当字符串拼接时,如果其中一个是变量(比如我们这里的s1),那么JVM就会在堆空间new一个String类的对象,用来存放字符串对象,然后该对象指向字符串常量池中对应的字符串数据。即我们的s2,s3指向的是堆中的对象,所以得到的结果当然是false。