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

参考:知乎专栏《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`与`==`)