java运行时常量池

jvm学习系列文章

Posted by zhenghao on 2018-09-28

java运行时常量池

public class Test {
public static void main(String [] args){
    String s1="abc";
    String s2="abc";
    String s3=new String("abc");
    System.out.println(s1==s2);
    System.out.println(s1==s3);
    System.out.println(s1==s3.intern());
}
}

上面代码的输出结果为 true false true

分析一下
j1
解释一下上面这张图,java虚拟机把类加载到内存中,执行main方法,这时候会在java虚拟机栈中创建栈帧,然后创建局部变量表S1 和S2的引用。然后再字符串常量池中放入abc这个字符串,同时把引用地址赋给S1.对于S2一样会把abc放入字符串常量池中,由于S1的存在已经在字符串常量池中放入了abc,这时候不会在创建重复的abc。这时候S2也持有abc的引用,所以S1 和S2引用指向的地址是一样的,所以第一个输出为true.

S3创建时new了一个对象,new的对象会存放到堆内存中,然后S3指向堆内存中的地址这时候S1和S2地址不一样所以返回是false

当S3调用了intern()方法的时候,它会去检查字符串中是否有abc,如果有直接把abc的引用直接返回,如果没有把abc加入到字符串常量池中在返回引用。而现在字符串常量池中已经有了abc,所以s1和s3都持有相同的引用地址,所以会返回为true。