理解String拼接,+运算符重载的实际效果

引申:一个常见的String的面试题

public static void main(String[] args) {
        // TODO Auto-generated method stub
        String s1 = "Hello";
        String s2 = "World";
        String s3 = "Hello"+"World";
        String s4 = s1+s2;
        String s5 = "HelloWorld";
        
        System.out.println(s3==s5);//true
        System.out.println(s3.equals(s5));//true
        System.out.println(s4==s5);//false
        System.out.println(s4.equals(s5));//true
        
        
    }

这里我们发现同样是使用了+号运算符作为字符串的拼接,但是常量"Hello"+"World"和s1+s2的结果并不相同。

我们已经知道java在存储字符串的时候,字符串是常量;它们的值在创建之后不能更改。那么在栈中 s3 是指向了helloworld的方法区的,那么s1+s2如果没有开辟空间(一般开辟空间使用的new,但是这里并没有进行new)应该也是指向了helloworld方法区的,值应该是一样的才对,那怎么会出现2种不同的情况。

实际上,在jdk文档中已经说明了这种情况

java 语言提供对字符串串联符号("+")以及将其他对象转换为字符串的特殊支持。字符串串联是通过 StringBuilder(或 StringBuffer)类及其 append 方法实现的。字符串转换是通过 toString 方法实现的,该方法由 Object 类定义,并可被 Java 中的所有类继承。

这里我们可以分析出其实 s1+s2是进行了new 一个StringBuilder来作为拼接的。那这样我们来反编译一下验证一下这个情况

使用Xjad反编译

这里我们看到了两个常量作为拼接的时候,编译器已经做了一次合并,所以s5和s3一模一样,s4=s1+s2,这里是new了一个StringBuilder然后append字符串s2然后转为string的。这里明显是开辟了新的堆空间。所以s4不等于s5。

原文地址:https://www.cnblogs.com/gavinjunftd/p/9322291.html