一.不可改变String

String对象是不可改变的, 
查看JDK文档,发现String类中每一个看似修改String的方法,实际上都创建了一个新的String对象,而最初的String对象则丝毫未动.

java传递参数的时候,传递的是引用的一个拷贝,调用时,都会复制一份引用,而引用所指向的对象,一直呆在某一单一物理位置,从未变动过.

二.重载 “+” 与 StringBuilder

String对象是不可改变的,你可以给一个String对象加任意多的别名. 
String对象是只读的,所要指向它的任何引用都不可能改变它的值.so不会对其他引用产生什么卵影响. 
用于String类中的”+” / “+=” 是Java中仅有的两个重载过的操作符,而java并不允许我们重载任何操作符;

public class one {
    public static void main(String[] args) {
        String a = "abc";
        String b = "123" + a + "def" + 777;
        System.out.println(b);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

如上代码,可能这样工作: 
String有append方法,然后返回一个新的String对象的引用,以包含连接后的字符串,然后再append , 再创建新对象. 
这种方式当然行得通,但是为了生成最终的String,次方式会产生一堆需要垃圾回收的中间对象.然后发现其性能略lowBi.那么编译器真的会这样做吗?

来来~~,反编译生成的.class

javap -c one.class 
这是JDK自带的工具 javap -c参数生成字节码

这里写图片描述

懂点汇编就行,,dup,invokevirtural 就是jvm上的汇编.

看好了: 
6: dup 
7: invokespecial #4 // Method java/lang/StringBuilder.””:()V 
10: ldc #5 // String 123 
12: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;


编译器自动引用java.lang.StringBuilder类,用以构造最终的String,为每个”+”调用一次append方法,最后调用toString方法生成最终的String并保存

三.what if 在循环里使用”+”呢

经过实验发现:

1.这样写:

String str = "";
for(int i = 0; i < num; i++)
{
    str += "a";
}
  • 1
  • 2
  • 3
  • 4
  • 5

javap -c

这里写图片描述

5~33是循环体, 15句创建一个StringBuilder对象

可知StringBuilder在循环体内构建,每次循环,创建新的StringBuilder

2.这样写:

 StringBuilder a = new StringBuilder();
for(int i = 0; i < 10; i++)
{
    a.append(i); //只有String能"+"
}
  • 1
  • 2
  • 3
  • 4
  • 5

这里写图片描述
只创建一个StringBuilder类

所以以后写的时候就知道咋回事了.

版权声明:本文为博主原创文章,转载请注明出处:http://blog.csdn.net/dextrad_ihacker http://blog.csdn.net/Dextrad_ihacker/article/details/53055709