String的拼接字符串的底层实现原理

下面代码:

public class Test1 {
    public static void main(String[] args) {
        String str1="hello";
        String str3="hello word!";
        String str4=str1+"word!";
        System.out.println(str3==str4);//false
    }
}

结果为:
在这里插入图片描述
String str3=“hello word!”;此句执行完之后,会将str3放入常量池;
String str4=str1+“word!”;结果也是 hello world,为什么str3==str4的结果为:false;
按照String对象创建的原理,str4是采用直接赋值的方法创建的,不是应该复用常量池中的str3的对象吗,结果不应该是true吗,但为什么是false呢?
(1) String的“+”拼接字符串,其真正实现的原理是中间通过建立临时的StringBuilder对象,然后调用append方法实现,然后再调用StringBuilder对象的toString方法将该StringBuilder对象转化为String对象,但StringBuilder对象的toString方法中是新new了一个String对象;
(2) String str4=str1+“word!”;语句执行过程为:创建一个StringBuilder对象,比如sb,然后调用append方法,sb.append(str1)和sb.append(“world!”);此时sb的值为:“hello word!”,然后再调用toString方法,通过观察源码

public String toString() {
        // Create a copy, don't share the array
        return new String(value, 0, count);
    }

可以发现:StringBuilder对象的toString方法中是新new了一个String对象,所以str4是指向一个使用new新创建出来的一个对象,不会复用常量池中的对象;
所以str3的地址是和str4的地址不同的,所以结果为false;

观察另外一段代码,在查找资料时碰巧遇到的,就顺便学习了一下:

public class Test1 {
    public static void main(String[] args) {
        String str1 = null;
        String str2 = "hello";
        String str = str1 + str2;
        System.out.println(str);//nullhello
      
    }
}

通过运行可知结果为:nullhello
为什么呢?

通过观察源码:

public AbstractStringBuilder append(String str) {
        if (str == null)
            return appendNull();
        int len = str.length();
        ensureCapacityInternal(count + len);
        str.getChars(0, len, value, count);
        count += len;
        return this;
    }
    
  
private AbstractStringBuilder appendNull() {
        int c = count;
        ensureCapacityInternal(c + 4);
        final char[] value = this.value;//在源码中可找到  char[] value为空
        value[c++] = 'n';
        value[c++] = 'u';
        value[c++] = 'l';
        value[c++] = 'l';
        count = c;
        return this;
    }

可知,如果str=null,sb.append(str)会返回一个null;

所以该段代码的结果为:null222222

你可能感兴趣的:(String的拼接字符串的底层实现原理)