前言:铁汁们,今天又是代码被虐爆肝的一天,被啥虐了嘞,看标题就知道了,话不多说上代码。
public class StringInternTest {
public static void main(String[] args) {
String s1 = "1";
String s= new String("1");
s.intern();
System.out.println(s == s1);
String s3 = new String("a") + new String("b");
s3.intern();
String s4 = "ab";
System.out.println(s3 == s4);
}
}
运行结果是这样:
起初我觉得不可思议,两串差不多的代码,运行结果却是截然相反,而且
在我的印象里,String类型的数据判断是否相等要用equals方法,定义两个String类型的变量用==号判断结果为true我还是头一次见到,真是越学越放弃。所以不懂就要问度娘:
Java为了提高性能,对基本数据类型和String类型提供了常量池的概念,相当于就是做了缓存处理了。
对于String类型数据:
- 直接使用双引号声明出来的String对象会直接存储在常量池中。
- 如果不是用双引号声明的对象,可用使用String的intern方法。intern方法会从字符串常量池中查询当前字符串是否存在,若不存在就会将当前字符串放入常量池中。
啥意思?
先看下s和s1
结果同我预想的一样,s1指向的是常量的地址,s是指向堆中的地址,二都不相等,结果为false。
再来看下s3和s4:
但是不对啊,我s3还是指向的堆里面的地址,s4是指向的常量池里面的地址,这不还是一样不相等吗?
纠结了很久才找到答案:
JDK7之前确实是这样,直接复制一个字符串放到常量池中,而在JDK7之后,常量池就放进堆里面一起存放了,所以不需要再复制对象而是直接添加对象的引用到常量池就可以了。
所以最终图可以这么画:
我是阿雷,我在秃头的路上等着你。