sql += ““,这样写字符串为什么不合适?

源于蚂蚁课堂的学习,点击这里查看(老余很给力)   

字符串算是所有语言的共性了,Java的字符串提供了两种拼接工具,StringBuilder和StringBuffer。但实际开发中,还是有很多猿友喜欢这样去拼接字符串。比如,写一个案例:

public class Test {
    public static void main(String[] args) {
        String a = "a";
        a += "b";
        a += "c";
    }
}

 这是我从事开发工作来的疑问,为什么前辈不推荐这样写,而且要使用StringBuilder或StringBuffer呢?

其实我们使用javap -c -v 你的class文件 指令去反编译可以查看到

 

这种非字符串常量池中的字符串引用参与运算,编译器不会直接把字符串做拼接,而且底层采用了StringBuilder去进去append,然后再做toString处理。

但StringBuilder的toString是new了一个新的String对象。试想,如果我们这样的操作有很多,岂不是会创建很多个String对象吗?

当然这并不意味着我们不能使用这种写法,比如: 

public class Test {
    public static void main(String[] args) {
        String a = "a"+
         "b"+"cd";
    }
}

这种字符串常量池中的非引用的字符串是可以参与运算的,因为编译器底层会将他们都合成一个字符串,放入字符串常量池中,本地上指向的地址也是常量池中的地址。 

 下面我们来看几个常见的面试题

public class StringTest {
    public static void main(String[] args) {
        String a = "a";
        String b = "b";

        String s1 = "ab";
        String s2 = "a" + "b";
        String s3 = a + "b";
        String s4 = a + b;
        String s5 = new String("ab");
        String s6 = (a + b).intern();
        String s7 = s5.intern();

       
        System.out.println(s1 == s2);
        System.out.println(s1 == s3);
        System.out.println(s1 == s4);
        System.out.println(s1 == s5);
        System.out.println(s1 == s6);
        System.out.println(s1 == s7);
    }
}

 这里的比较都是==,也就意味着比较地址。

那么s1是字符串常量池中的内容,所以s1指向的就是堆内存中字符串常量池中此常量的地址。

s2是两个字符串常量的拼接,编译器会做自动的拼接,然后放入常量池,常量池已有,则直接将s2的地址指向此常量。

s3中存在引用与字符串的拼接运算,底层采用StringBudiler去append,然后通过toString去new出一个新的String对象,所以s3指向的是堆内存中新对象的地址。

s4与s3同理,都是创建一个新的字符串对象。

s5直接new,所以也是指向堆内存新字符串对象。(注意,s3/s4/s5指向的是各自创建处理的字符串对象)。

s6是将两个字符串引用运算后,做intern处理。字符串运算,创建了新的对象,但是他的内容,通过intern操作,被放入了字符串常量池中,并返回其在常量池中的地址。

s7同s6。

所以结果为true false false false true true

欢迎大家和帝都的雁积极互动,头脑交流会比个人埋头苦学更有效!共勉!

公众号:帝都的雁

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值