Java基礎-- ==號與equals()方法的區別

小小開發發表於2018-08-22

==號和equals()方法都是比較是否相等的方法,那它們有什麼區別和聯絡呢? 首先,==號在比較基本資料型別時比較的是值,而用==號比較兩個物件時比較的是兩個物件的地址值:

int x = 10;
int y = 10;
String str1 = new String("abc");
String str2 = new String("abc");
System.out.println(x == y); // 輸出true
System.out.println(str1 == str2); // 輸出false
複製程式碼

那equals()方法呢?我們可以通過檢視原始碼知道,equals()方法存在於Object類中,因為Object類是所有類的直接或間接父類,也就是說所有的類中的equals()方法都繼承自Object類,而通過原始碼我們發現,Object類中equals()方法底層依賴的是==號,那麼,在所有沒有重寫equals()方法的類中,呼叫equals()方法其實和使用==號的效果一樣,也是比較的地址值,然而,Java提供的所有類中,絕大多數類都重寫了equals()方法,重寫後的equals()方法一般都是比較兩個物件的值:


public class Demo1 {

    public static void main(String[] args){
        Student studentA = new Student(23);
        Student studentB = new Student(23);
        System.out.println(studentA.equals(studentB));
    }

}

class Student{
    private int age;

    public Student() {
    }

    public Student(int age) {
        this.age = age;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
複製程式碼

這裡我自己定義了一個Student類,沒有重寫equals()方法,最後的輸出結果是:false


public class Demo1 {

    public static void main(String[] args){
        Student studentA = new Student(23);
        Student studentB = new Student(23);
        System.out.println(studentA.equals(studentB));
    }

}

class Student{
    private int age;

    public Student() {
    }

    public Student(int age) {
        this.age = age;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public boolean equals(Object o){
        Student student = (Student) o;
        return this.getAge() == student.getAge();
    }
}
複製程式碼

在我重寫了equals()方法後,輸出結果變成了true。

現在一些基本的已經講的差不多了,接下來我們回到第一個例子:

String str1 = new String("abc");
String str2 = new String("abc");
System.out.println(str1.equals(str2));
System.out.println(str1 == str2);
複製程式碼

根據上面所講,第一個是true,第二個是false,確實如此,那繼續看下面的例子:

String s1 = "abc";
String s2 = "abc";
System.out.println(s1.equals(s2));
System.out.println(s1 == s2);
複製程式碼

這次的結果和上一個的是一樣的嗎?答案是:true true 為什麼第二個會是true呢? 這就涉及到了記憶體中的常量池,常量池屬於方法區的一部分,當執行到s1建立物件時,如果常量池中沒有,就在常量池中建立一個物件”abc”,第二次建立的時候,就直接使用,所以兩次建立的物件其實是同一個物件,它們的地址值相等。

那上一個例子中的

String str1 = new String("abc");
複製程式碼

是怎麼回事呢? 這裡其實建立了兩次物件,依次是在常量池中建立了物件”abc”,一次是在堆記憶體中建立了物件str1,所以str1和str2的地址值不相等。

相關文章