美文网首页Java 小细节
Java字符串之`equals`与`==`

Java字符串之`equals`与`==`

作者: 谢随安 | 来源:发表于2017-09-26 15:51 被阅读11次

    参考:知乎专栏《Java那些事儿》

    其实前段时间自己写代码的时候就注意到这个问题了,不过那时候并没有写下来的想法,现在复习Java基础又看到相关的文章,就当练习Markdown把这个问题写下来好了。


    执行如下代码:

    public class StringCmp {
        public static void main(String[] args) {
    
            String str1 = "abc";
            String str2 = "abc";
    
            String str3 = new String("abc");
            String str4 = new String("abc");
    
    
            System.out.println("Using `==`:");
            System.out.println("str1 == str2:" + (str1 == str2));
            System.out.println("str3 == str4:" + (str3 == str4));
    
            System.out.println("Using `equals`:");
            System.out.println("str1.equals(str2):" + str1.equals(str2));
            System.out.println("str3.equals(str4):" + str3.equals(str4));
    
        }
    }
    

    执行结果如下:

    Using `==`:
    str1 == str2:true
    str3 == str4:false
    Using `equals`:
    str1.equals(str2):true
    str3.equals(str4):true
    

    equals的结果是我们预期想要的,但==却不是,这是为何呢?
    然而这次出现不同结果的原因却与Integer那篇文章的原因不同----这次并非是编译器的锅,编译器并没有在编译的时候偷偷修改代码。

    原因在于:

    1. 当代码执行到String str1 = "abc",就在堆空间的常量池中查询"abc"这个对象,发现常量池中没有,则在常量池里创建并初始化该对象,并将引用指向它。
    2. 当代码执行到String str2 = "abc",同样在堆空间的常量池中查询"abc"这个对象,发现常量池中存在该对象,于是将引用同样指向"abc"。

    而由于str1,str2 两个对象指向同一个引用,因此str1 == str2输出为true。

    str3 == str4 的结果为false的原因在于:

    • 当代码执行到String str3 = new String("abc");String str4 = new String("abc");时,new关键字告诉JVM要在堆空间里使用一段新的空间用来创建一个新的对象。所以JVM为
      str3str4 都分别在堆空间中创建了一个属于它们的空间。
      因此执行 str3.==(str4)时,由于 str3str4 不是指向同一个引用,因此结果为false。

    结论: == 的意义是内存地址的比较,而非值本身,比较值一定要使用equals去比较,Java并不支持重载操作符

    相关文章

      网友评论

        本文标题:Java字符串之`equals`与`==`

        本文链接:https://www.haomeiwen.com/subject/xetsextx.html