+ 拼接生成的字符串是在字符串常量池在是在堆中?

勤奋好学

“+” 拼接生成的字符串是在字符串常量池在是在堆中? 这个问题问的方式有些谬误,JDK7时字符串常量池已经从永久代移到堆中了,也就是说JDK7时字符串常量池是堆的一部分。如此看来,这个问题的答案即是 既在。。又在。。

而且,关于字符串对象的问题是和程序的上下文环境有关系的。比如JDK版本、之前是不是已经存在了该字符串对象啊 、使用 “+” 在字面量之间还是在new String()之间啊 等等。。影响因素有很多的


 class StringinternDemo {
     public static void main(String[] args) {
         System.out.println(System.getProperty("java.version"));
         String str1 = "ab";
         String str2 = new String("ab");
         String str3 = "a" + "b";
         String str4 = new String("a") + new String("b");

         System.out.println(str1 == str2); //f
         System.out.println(str1 == str3); //t
         System.out.println(str1 == str4); //f
         System.out.println(str2 == str3);  // f
         System.out.println(str2 == str4); // f
         System.out.println(str3 == str4); // f

     }
 }

经测试上面代码在JDK6、JDK7中均是false、true、false、false、false、false

"a" + "b"

这种情况,直接进行字面量的拼接。编译器会将之优化为"ab"。我们可以打开字节码,反编译之看看:


image.png
new String("a") + new String("b") 情况比较特殊

new String("a") + new String("b")可分解为new String("a")和new String("b"),在执行这两步操作时,都会先去字符串常量池中查找是否存在"a"和"b",若没有,则在字符串常量池中创建"a"和"b"两个对象,然后再在堆中创建new String("a")和new String("b")两个对象。

否则直接在堆中直接创建new String("a")和new String("b")两个对象。之后会将两个字符串进行拼接,拼接后会再在堆中创建一个new String("a"+"b")对象。

因此若原本字符串常量池中没有"a"和"b",执行String str4 = new new String("a") + new String("b") 会创建5个对象;(字符串常量池2个+堆中3个 )
若字符串常量池中已经存在了"a"和"b"则只在堆中创建3个对象。

你可能感兴趣的:(+ 拼接生成的字符串是在字符串常量池在是在堆中?)