多次字符串相加一定要用StringBuilder而不用-吗?
今天再写一个读取Java class File并进行分析的Demo时 , 偶然发现了下面这个场景(基于oracle jdk 1.8.0_144):
package test;public class Test8 {String s1 = "111", s2 = "222", s3 = "333", s4 = "444";public String test() {return s1 + s2 + s3 + s4 + "5555" + "66666666666666666666666666" + "777" + new String("测试测试") + String.valueOf("test test") + "长字符串长字符串长字符串长字符串长字符串长字符串长字符串长字符串长字符串长字符串长字符串长字符串";}}
【多次字符串相加一定要用StringBuilder而不用-吗?】这是一个很简单的类 , 只完成了字符串的 + 操作 , 我们查看对应生成的class文件的outline:
// class version 52.0 (52)// access flags 0x21public class test/Test8 {// compiled from: Test8.java// access flags 0x0Ljava/lang/String; s1// access flags 0x0Ljava/lang/String; s2// access flags 0x0Ljava/lang/String; s3// access flags 0x0Ljava/lang/String; s4// access flags 0x1public
请注意这段:
// access flags 0x1public test()Ljava/lang/String;L0LINENUMBER 8 L0NEW java/lang/StringBuilderDUPINVOKESPECIAL java/lang/StringBuilder.
我们可以看到 , 即便我们没有显式的使用StringBuilder , 实际上编译器也会隐式的将我们的 + 运算符优化为StringBuilder的append()操作;另外 , 其中字符串常量的相加这里 , 也就是 "5555" + "66666666666666666666666666" + "777" 这里对应的操作是:
GETFIELD test/Test8.s4 : Ljava/lang/String;INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;LDC "555566666666666666666666666666777"
直接被合并在了一次(具体这是什么操作我不是很明白)
这时候我就想起来 , 原来一直被教导的“字符串相加一定要用StringBuilder而不要用 + ”真的正确吗?这个值得深思 。
2017-01-22更新:
GETFIELD test/Test8.s4 : Ljava/lang/String;INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;LDC "555566666666666666666666666666777"
直接被合并在了一次(具体这是什么操作我不是很明白)
这里可能是编译器做了“公共的表达式消除”这个优化操作 (这里是错误的 , 请看后边的勘误)
2017-01-25更新:
在循环+=的情况下 , 编译器也会做优化工作的 , 但是IDE仍然会给出警告 , 不知道编译器的优化是否在所有情况下均会触发(有待继续学习)
public static void main(String[] args) {String s = "";for (int i = 0; i < 10000; i++) {int int_ = new Random().nextInt();s += int_;}System.out.println(s);}
文章插图
- ICPC--1199: 在线判题(字符串)
- ICPC--1206: 字符串的修改&1207:字符排列问题
- 红米太稳了,8+512G多次被抢光,友商望尘莫及
- Golang面试字符串、数组、切片知识
- 多次开售都秒没,12+256G新机仅3699元,价格太香
- 十六、深入Python字符串
- 零基础学Python:一文看懂数字和字符串
- leetcode之字符串压缩
- 年后|马云、任正非多次提到,10年后国内最贵的不是房子,而是这样东西
- listing|如何实现同一个listing一周内多次上Lightning Deals