关于String的学习笔记:
直接上代码。我的JDK版本是1.8
String str1 = "ab";
String str2 = new String("ab");
String str3 = "a"+"b";
System.out.println(str1==str2);
System.out.println(str1==str3);
运行结果:
str1 == str2 // false
str1 == str3 // true
首先,==对于引用型变量判断的是其地址值是否相等。
String对象(例如ab)的创建过程是,在创建过程中,会先去常量池中找是否有该对象或者该对象的引用,如果有则直接返回该对象或者其引用,否则的话会在常量池中建立该对象(ab)。在JDK1.7以前常量池是存储在方法区中,1.7及其以后被放在了堆内存里。
因此 str1是指向常量池中的ab。
我们知道new是创建对象的过程,凡是new出来的对象,那么他都会被存储到堆内存中。当然,在new的过程中,JVM还会去常量池中看看有没有ab这个常量,如果有就不管了,没有的话会把该常量ab创建出来放在常量池中。
但是需要注意自始至终str2是始终指向的是堆内存中的对象ab。
所以 str1==str2 返回的是false
在Java程序编译时,JVM会自动的完成字符串的拼接,实际上编译时就被拼接成了ab,相当于str3指向的是常量池中的ab
所以 str1==str3 返回的是true
我们继续来看:
String str4 = new String("ab");
String str5 = new String("a") + new String("b");
System.out.println(str4==str5);
运行结果:
str4 == str5 // false
在new创建对象的过程中即便引用的内容是相同的,他们也是不同的个体,地址值是不同的,可以理解为两个独立的人他们只是名字相同而已,性格什么都不一样。
因此 str4 == str5 返回false
keep going:
String str6 = new String("a")+new String("b");
String str7 = str6.intern();
String str8 = "ab";
System.out.println(str6==str7);
System.out.println(str7==str8);
运行结果:
str6 == str7 // true
str7 == str8 // true
在此之前,我们要介绍一下String.intern()方法,该方法的作用是重复利用String对象,减少不必要的对象创建次数,因此可以节约内存。
分析:
str6指向的是堆内存的ab对象
str6.intern是什么意思呢?
在JDK1.7以前 ,如果常量池里面没有ab,会直接创建一个ab对象放在常量池里面。
在JDK1.7及其以后,则是创建一个引用指向的是堆中的ab
因此 str6.intern是在常量池中创建了一个引用指向了堆中ab对象,str7指向了这个引用那么也相当于指向了堆中ab对象
因此str6 == str7 返回true
同理,str8同样指向的是指向堆中ab的引用
因此str7 == str8 返回true
ps:
第一次写博客,有不对的还请各位大佬指正