JVM(3)

43 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 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 将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有会把此对象复制一份, 放入串池, 会把串池中的对象返回