我们先来看下用"+"来拼接出的字符串和直接用字面值创建的字符串地址值是否相等。

        String str = "qw" + "er";
        String qwer = "qwer";
        System.out.println(qwer == str);//结果为ture

用"+"拼接的字符串和直接创建的字符串地址值是相等的,说明strqwer指向的是同一个地址。

我们在看下"+="来拼接的字符串和字面值创建的字符串地址是否相等。

        String str="qw";
        str+="er";
        String qwer="qwer";
        System.out.println(qwer==str);//结果为false

用"+="来拼接的字符串和直接创建的字符串地址值是不相等的,说明strqwer指向的不是同一个地址。 那么这时候str指向的是哪里呢?"+="又做了什么操作呢?

首先qwer是指向字符串常量池的,那么strqwer字符串内容相同但是地址不同,说明str并没有指向字符串常量池。其实这时候str指向了堆内存。为什么呢?

因为在str+="er";这里时,JVM对"+="进行了重载,这里实际执行的是

        String str="qw";
        StringBuilder sb=new StringBuilder(str);
        str = sb.append("er").toString();
        String qwer="qwer";
        System.out.println(qwer==str);//结果为false

从上面代码我们可以看到之前的str+="er";,实际是以str对象生产StringBuider对象,然后调用append()方法依次拼接字符串。


那么我们接下来做一个实验如果用"+"来拼接两个变量,会发生什么呢?

        String qw="qw";
        String er="er";
        String qwer=qw+er;
        String str="qwer";
        System.out.println(qwer==str);//结果为false

哦嚯!结果也为false,那么是不是说明:"+"也是被重载过了呢???

我们再看一个例子

        String str=new String("qw")+new String("er");
        String qwer="qwer";
        System.out.println(str==qwer);//结果为false

new关键字创建的两个String对象通过"+"来拼接结果也为false。 其实"+"也是被重载过了,只不过是"+"前后有变量时才会重载。