String相加的比较

这篇博客探讨了Java中字符串比较的细节,包括`==`和`equals()`方法的使用,以及`intern()`方法的作用。通过示例代码展示了字符串常量池的工作原理,解释了为何在不同情况下字符串引用可能相等或不等。内容涵盖了字符串拼接优化、动态对象创建以及final变量的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

public class StringCompare {
    
    public static void main(String[] args) {

        String s1 = "Hello";
        String s2 = "Hello";
        String s3 = "Hel" + "lo";
        String s4 = "Hel" + new String("lo");
        String s5 = new String("Hello");
        String s6 = s5.intern();
        String s7 = "H";
        String s8 = "ello";
        String s9 = s7 + s8;

        final String a = "H";
        final String b = "ello";
        String s10 = a + b;

        // == 与 equals方法都是比较地址,如果重写了equals方法,则比较的是内容,
        //String重写了equals方法

        // JVM会首先去常量池中查找是否有”Hello”这个字符串常量,有的话就返回引用地址给s1,
        // 没有就将”Hello”字符串常量放入常量池,再返回地址给s1,s2也是”Hello”字符串常量,
        // 因此JVM会将常量池中的该字符串引用地址返回给s2,
        //因此实际上s1和s2指向的是同一个字符串字面量
        // 所以才会为true。
        System.out.println(s1 == s2);  // true


        //”Hel“与”lo“都在堆中,常量相加的时候,其实是在编译期就直接相加为“Hello”,
        //这是JVM的优化,不会创建 StringBuilder 对象
        // 所以运行的时候,s1和s3的字节码是一样的。因为在常量池中有了一个“helloword”,
        // 所以两个引用指向的是一个字符串“helloword”,所以返回结果也是true。
        System.out.println(s1 == s3);  // true

        //!动态调用,创建StringBuffer对象,然后调用append方法,返回的都是String对象

        // s4是分别用了常量池中的字符串和存放对象的堆中的字符串,
        //其实是创建了一个StringBuffer对象,
       //然后用StringBuffer对象执行append方法来创建出字符串对象“Hello”,然后再转换成为String。
        // 做+的时候会进行动态调用,最后生成的仍然是一个String对象存放在堆中。
        System.out.println(s1 == s4);  // false

       //进行了动态调用,这个转换后的是个String对象,也就是s9是放在堆里面的。
       //而s1则是字符串常量,放在常量池里面。
        // 所以返回的是false。
        System.out.println(s1 == s9);  // false

        //s4与s5都是不同的String对象,所以地址不同
        System.out.println(s4 == s5);  // false

        //为啥s1 和 s6地址相等呢? 归功于intern方法,
        // 这个方法首先在常量池中查找是否存在一份equal(内容)相等的字符串,
        //如果有的话就返回该字符串的引用,
        // 没有的话就将它加入到字符串常量池中,
        // 所以存在于class中的常量池并非固定不变的,可以用intern方法加入新的
        System.out.println(s1 == s6);  // true

        //当final变量是基本数据类型以及String类型时,如果在编译期能知道它的确切值,
        //则编译器会把它当做编译期常量使用。
        // 也就是说在用到该final变量的地方,相当于直接访问的这个常量,不需要在运行期确定。
        System.out.println(s1 == s10);  // true


    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值