深入理解java String与JVM常量池
创建一个String有二种形式
第一种形式:
String a = "abc";
String b = "abc";
a引用的字符串存放在常量池中,当创建b引用的字符串时,会先从常量池中查找有没有该字符串,如果有,就返回常量池中的字符串。如果没有,就创建该字符串对象并放在常量池中,因为字符串非常常用,jvm为了提高性能和减少内存开销,就会做这些优化。
下面再举几个例子
例一
String a = "abc";
String b = "abc";
System.out.println(a == b);
执行上述代码 : 结果为true
a和b引用指向的的都是常量池中同一个String对象的地址
例二
String a = "abc";
System.out.println(a == "abc");
你可能会认为结果为true,不过事情总是没想象的那么简单,
如果使用debug模式,得到的结果为false!
分析:首先实例化了"abc"字符串并存放到JVM的常量池中。
常量池分为编译期常量池和运行时常量池
常量池分为编译期常量池和运行时常量池
a == "abc"这段代码里的"abc"是未赋值的的,jvm会对String常量的运算进行优化,未声明的字符串不会在编译器常量池,只有当你运行时才会实例化字符串到运行时常量池中,而声明的a在编译器常量池,所以debug为false。让我们回到print(a == b) //true print这段代码在JVM编译期可能会跳过,所以,在print内部定义的"abc"是运行期获取的,比较对象地址,结果输出为true;