jvm的角度理解字符串(常量池与串池、字符串的拼接)

一、常量池与串池

1、书写代码:

public class test1804 {
    public static void main(String[] args) {
        String string1="a";
        String string2="b";
        String string3="ab";
    }
}

2、查看字节码

jvm的角度理解字符串(常量池与串池、字符串的拼接)

 常量池中的信息,都会被加载到运行时常量池,这时a,b,ab都是常量池中的符号,还没有变为java字符串对象

执行到此处的时候变为字符串对象,被存放在串池中:

jvm的角度理解字符串(常量池与串池、字符串的拼接)

 先去串池(hashtable结构,不能扩容)中查找是否有a,如果已经有a就不会再去创建字符串对象,没有的话 #2会把符号a变为字符串对象a,b和ab一样

二、字符串变量的拼接

1、代码

public class test1804 {
    public static void main(String[] args) {
        String string1="a";
        String string2="b";
        String string3="ab";
        String string4=string1+string2;
    }
}

2、字节码

jvm的角度理解字符串(常量池与串池、字符串的拼接)

 3、拼接的过程

jvm的角度理解字符串(常量池与串池、字符串的拼接)

 实质上是执行的下面的一段代码:

new StringBuilder().append("a").append("b").toString();

4、拼接字符串的比较

(1)方式一:

public class test1804 {
    public static void main(String[] args) {
        String string1="a";
        String string2="b";
        String string3="ab";
        String string4=string1+string2;
        System.out.println(string3==string4);
    }
}
false

string3在串池中,string4在堆里面(https://www.cnblogs.com/zhai1997/p/12423092.html

方式二:

public class test1804 {
    public static void main(String[] args) {
        String string1="a";
        String string2="b";
        String string3="ab";
        String string4="a"+"b";
        System.out.println(string3==string4);
    }
}
true

字节码执行过程:

jvm的角度理解字符串(常量池与串池、字符串的拼接)

 直接找到拼接好的字符串“ab”,并且存入到地址为5的地方,实际上是javac在编译期的优化,结果已经在编译期确定为字符串“ab”,而上一个拼接是不能在编译期确定的

相关推荐