1、原理
参考学习视频:
https://www.bilibili.com/video/BV1WK4y1M77t/?spm_id_from=333.337.search-card.all.click&vd_source=4dc3f886f5ce1d43363b603935f02bd1
String s1 = “hello”;
String s1 = "hello";
代码原理解释如下图
String s1 = new String(“hello”)
String s1 = new String("hello")
1、先在堆中创建保存hello的内存,然后创建oop对象指向这块内存地址
2、根据反编译的jvm指令代码有ldc指令,所以会去常量池找下看有没有该字面量,
如果没有则创建,有则不处理
反编译代码如下:
0 new #2 <java/lang/StringBuilder>
3 dup
4 invokespecial #3 <java/lang/StringBuilder.<init>>
7 new #4 <java/lang/String>
10 dup
11 ldc #5 <hello> # 注意这行代码,ldc就是去常量池会有没有该字面量,没有则创建
13 invokespecial #6 <java/lang/String.<init>>
16 invokevirtual #7 <java/lang/StringBuilder.append>
19 new #4 <java/lang/String>
22 dup
23 ldc #8 <world>
25 invokespecial #6 <java/lang/String.<init>>
28 invokevirtual #7 <java/lang/StringBuilder.append>
31 invokevirtual #9 <java/lang/StringBuilder.toString>
34 astore_1
35 return
intern
用法如:
String s1 = new String("1") + new String("2"); # 在常量池只会创建2个常量对象
指向1和 2。而堆中会创建三个对象,1和 2和12
下图我从B栈上直接截图,不想画图了
String s1 = new String("1") + new String("2");
s1.intern(); # 这句话会在常量池生成12对象,并且hashmap的value指向堆中的12。
String s2 = "12";
System.out.println(s1 == s2); // true
下图省略掉上面1,2这些对象的画图,只保留最后的图形
String s1 = new String("hello") + new String("world");
String s2 = "helloworld";
s1.intern(); //不管这行代码有没有,结果都是false
System.out.println(s1 == s2); // false
这个代码最后是false,是因为s2常量池对象先创建,和堆中堆中对象内存地址不一样