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

勤奋好学

“+” 拼接生成的字符串是在字符串常量池在是在堆中? 这个问题问的方式有些谬误,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个对象。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 概述 在分析字符串常量池之前,先来分析一下java的内存区域,然后再各种的情况分析一下各种情况下的情况; 在《深入...
    riverhh阅读 839评论 0 2
  • JVM中的字符串常量池是个有些玄幻的玩意儿,关于它的细节,各类书籍和网站上众说纷纭。本文试图参考尽量权威的资料,找...
    LittleMagic阅读 3,137评论 8 20
  • 在JVM中,为了减少字符串对象的重复创建,维护了一块特殊的内存空间,这块内存就被称为字符串常量池。 在JDK1.6...
    烟雨星空阅读 401评论 0 0
  • 在写之前我们先来看几个问题,假如你对这些问题已经很懂了的话,那大可不用看这篇文章,如果不大懂的话,那么可以看看我的...
    帅地阅读 394评论 0 5
  • 前言 RTFSC (Read the fucking source code )才是生活中最重要的。我们天天就是要...
    二毛_coder阅读 469评论 1 1