最近看尚硅谷2020最新版宋红康JVM教程更新至中篇(java虚拟机详解,jvm从入门到精通)视频,解决了部分java String方面的疑惑,在此做个笔记。
##0. Sting a = s.intern() 之intern()方法
从字符串常量池中查询是否存在字符串“s”。
若存在,则将此地址指向a;
若不存在,则:
- jdk1.6中:在常量池中new出该字符串(“s”),并将其指向a。
- jdk1.7及以上中:堆空间中有“s”,则在常量池中创建指向堆空间中s的引用;否则,在常量池中new出该字符串(“s”),并将其指向a(同上)。
*jdk1.6之前的常量池不在堆中,在方法区中,故而画在外面。 |
---|
##1. String a = “ab”
“ab”直接存到了常量池中。
##2. String a = new String(“ab”)
实质上new了两个对象:1.new了个String类型的对象,放在堆中;2.常量池中放入“ab”。 证据请看编译后的字节码(第一行和第三行):
1 | 0 new #2 <java/lang/String> |
证明常量池中有“ab”。
因此 "ab" == new String("ab")
为 false
##3. String a = new String(“a”)+new String(“b”)
字符串中的加号“+”本质操作为
StringBuild.append().toString()
操作
所以,此处先String了”a”,后String了”b”。再通过StringBuild.append().toString()
操作new出了对象“ab”,放在了堆中。常量池中仅有“a”和“b”,并没有“ab”。
现在再去看康老师讲的几道题目解析就很清晰了:
题目1
题目2
1 | public static void main(String[] args) { |
①new String(“ab”)在堆和常量池中均创建了“ab”,②intern直接创建常量池中的“ab”;③s2指向常量池中的“ab”。应该可以仿照上面画图进行解释了。