最近看尚硅谷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情况.png *jdk1.6之前的常量池不在堆中,在方法区中,故而画在外面。 | JDK1.7及以上情况 |
---|
1. String a = "ab"
"ab"直接存到了常量池中。
String a = "ab"示意图
2. String a = new String("ab")
实质上new了两个对象:1.new了个String类型的对象,放在堆中;2.常量池中放入“ab”。 证据请看编译后的字节码(第一行和第三行):
0 new #2 <java/lang/String>
3 dup
4 ldc #3 <ab>
6 invokespecial #4 <java/lang/String.<init>>
9 astore_1
10 return
证明常量池中有“ab”。
String a = new 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
题目1.pngJDK1.6情况 | JDK1.7及以上情况 |
---|
题目2
public static void main(String[] args) {
String s = new String("ab");
s.intern();
String s2 = "ab";
System.out.println(s == s2);//jdk1.6/1.7以上:答案均为 false
}
①new String("ab")在堆和常量池中均创建了“ab”,②intern直接创建常量池中的“ab”;③s2指向常量池中的“ab”。应该可以仿照上面画图进行解释了。
网友评论