关于String字符串相加的问题

关于String字符串相加的问题

网上很多人说是创建一个StringBuilder对象,再进行append追加,我不清楚是不是这样,Debug了一下代码,发现好像不是这样,分以下几种情况:

  • 两个new的字符串相加(底层调用的数组拷贝,然后创建String对象)
        System.out.println("============");
        // 两个newString相加得到一个新String对象,即s1指向堆中的一个新的String对象
        String s1 = new String("hello") + new String("123");
        // s2直接指向字符串常量池"hello123"的内存地址
        String s2 = "hello123";
        // s3是"hello"与"123"字符串拼接得到"hello123",也是直接指向字符串常量池"hello123"的内存地址
        String s3 = "hello" + "123";
        System.out.println(s1.hashCode());
        System.out.println(s2.hashCode());
        System.out.println(s3.hashCode());
        System.out.println(s1 == s2); // false
        System.out.println(s2 == s3); // true

在这里插入图片描述

在这里插入图片描述

  • 两个String字符串相加(底层同样是调用的数组拷贝的方法,再通过byte数组创建对象)
        // 两个String字符串直接相加其实和第一种情况是一样的
        // 第一种是先创建好了两个String,这一种是s1,s2直接指向方法区常量池中的字符串内存地址
        String s1="a";
        String s2="b";
        // 这里依旧会再new 一个String对象,底层同样调用的数组拷贝
        String s3=s1+s2;
        String s4="ab";
        System.out.println(s3 == s4); // false
  • 对第一种和第二种的解释:Debug打断点
    在这里插入图片描述
    进入MethodHandle方法
    在这里插入图片描述
    进入invokeStatic方法
    在这里插入图片描述
    进入到StringConcatHelper类,这个类是来自String字符串拼接的工厂,在这里执行simpleConcat方法,参数为两个相加的字符串
    在这里插入图片描述在这里插入图片描述
    在这个方法里首先会把两个参数转化为String类型
    在这里插入图片描述
    接着判断参数个数,根据个数创建一个byte[]数组
    在这里插入图片描述
    进入这个方法之后会调用数组拷贝的方法
    在这里插入图片描述
    在这里插入图片描述
    进入newString方法,并将数组作为参数传入
    在这里插入图片描述

调用String类的构造方法
在这里插入图片描述
在这里插入图片描述
这个时候就创建好了一个String对象,s3指向这个String对象,并引用其内存地址。
并且我反编译了字节码文件,发现底层使用的是StringConcatFactory工厂的方法:

SourceFile: "TestString.java"
BootstrapMethods:
  0: #52 REF_invokeStatic java/lang/invoke/StringConcatFactory.makeConcatWithConstants:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
    Method arguments:
      #58 \u0001\u0001
InnerClasses:
  public static final #65= #61 of #63;    // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles

在这里插入图片描述

  • 直接两个字符串相加
        System.out.println("==========");
        // 两个字符串直接相加,底层JVM会直接将两个字符串拼接,
        // 如果拼接后的字符串存在于常量池则直接指向其地址,
        // 否则在常量池创建一个字符串再指向其地址
        String z1 = "he" + "lm";
        String z2 = "helm";
        System.out.println(z1 == z2); // true
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值