开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第26天,点击查看活动详情
s3 == s4
分析一把:s1,s2的加载是懒惰化的,只有用到才会赋值,如果 StringTable中有该值,那么就可以直接调用
对于String s1 = "a";直接在StringTable中定义a
对于String s4 = s1 + s2;先new StringBuilder(),再调用append("a").append("b").toString(),这个操作会创建一个新的String对象
所以s3!=s4,因为s3存放在StringTable中,而s4存放在堆中,是两个对象
s3 == s5
由于都是在常量池中取值,并且常量池中有ab,因此两者相同,因为javac会对s5优化,结果已经在编译器确认为ab
s3==s6
相等,intern方法返回的是在StringTable中的对象
JDK1.8 intern栗子
上面栗子说明当StringTable中有了定义过的常量了,调用了intern无法将当前调用方对象放置StringTable中,
也就是说要是StringTable中有常量,那么调用方还是在堆中,要是没有,则变得StringTable中
jdk1.8的intern调用方要是StringTable中有该对象,则还是在堆中,没有该对象则将调用方放置StringTable中
JDK1.6 intern栗子
JDK1.6 的intern调用方不管原先的StringTable中有没有都还是一直存在在堆中
-
常量池中的字符串仅是符号,第一次用到时才变为对象
-
利用串池的机制,来避免重复创建字符串对象
-
字符串变量拼接的原理是 StringBuilder (1.8)
-
字符串常量拼接的原理是编译期优化
-
可以使用 intern 方法,主动将串池中还没有的字符串对象放入串池
- 1.8 将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有则放入串池, 会把串 池中的对象返回
- 1.6 将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有会把此对象复制一份, 放入串池, 会把串池中的对象返回