深入探究Java中equals()和==的區(qū)別是什么

相等判斷符"=="介紹

"=="相等判斷符用于比較基本數(shù)據(jù)類型和引用類型數(shù)據(jù). 當(dāng)比較基本數(shù)據(jù)類型的時候比較的是數(shù)值, 當(dāng)比較引用類型數(shù)據(jù)時比較的是引用(指針).

"=="判斷基本類型是否相等.

  • 首先基本數(shù)據(jù)類型指的是Java中的八大數(shù)據(jù)類型: byte, short, int, long, float, double, char, boolean
  • 這八大基本數(shù)據(jù)類型有個共同的特點是它們在內(nèi)存中是有具體值的, 比如說一個int類型的數(shù)據(jù)"2", 它在8位數(shù)據(jù)總線的機(jī)器上(假設(shè)的)保存形式為0000 0010.
  • 當(dāng)使用"=="比較兩個基本數(shù)據(jù)類型的時候, 就是比較它們各自在內(nèi)存中的值.

"=="判斷引用類型數(shù)據(jù)是否相等

  • 引用數(shù)據(jù)類型在字面上也是很好理解的, 就是一個引用, 它會指向一個具體的對象.
  • 比如說Student stu = new Student();, 這里的stu就是一個引用, 它指向的是當(dāng)前new出來的Student對象. 當(dāng)我們想要操作這個Student對象時, 只需要操作引用即可, 比如說int age = stu.getAge();.
  • 所以用"=="判斷兩個引用數(shù)據(jù)類型是否相等的時候, 實際上是在判斷兩個引用是否指向同一個對象.
  • 看下面的示例
public static void main(String[] args) {
    String s1 = "hello";    //s1指向常量池中的"hello"字符串
    String s2 = "hello";    //s2也指向常量池中的"hello"字符串
    System.out.println(s1 == s2);   //true

    String s3 = new String("hello");   //s3指向的是堆內(nèi)存中的字符串對象 
    System.out.println(s1 == s3);   //false
}

  • 從上面的例子可以看到, 由于引用"s1"和"s2"指向的都是常量池中的"hello"字符串, 所以返回true.
  • 而"s3"指向的是新創(chuàng)建字符串對象, 因為只要動用了new關(guān)鍵字, 就會在堆內(nèi)存創(chuàng)建一個新的對象,
  • 也就是說s1和s3指向的是不同的字符串對象, 所以返回false.

判斷是否相等-equals()方法介紹.

equals()和==有著本質(zhì)的區(qū)別, ==可以看作是對操作系統(tǒng)比較數(shù)據(jù)手段的封裝, 而equals()則是每個對象自帶的比較方法.

  • equals()和==的本質(zhì)區(qū)別更通俗的說法是, ==的比較規(guī)則是定死的, 如上面所述; 而equals()的比較規(guī)則是不固定的, 可以由用戶自己定義.

看下面的例子:

public static void main(String[] args) {
    String s1 = "hello";
    String s3 = new String("hello");    
    System.out.println(s1.equals(s3));  //true
}
  • 在用==比較的時候, 上面s1和s3比較出的結(jié)果為false. 而當(dāng)用equals比較的時候, 得出的結(jié)果為true.
  • 想知道原因我們還得看源碼, 下面是String類的equals()源碼.
public boolean equals(Object anObject) {
    if (this == anObject) { //先比較兩個字符串的引用是否相等(是否指向同一個對象), 是直接返回true
        return true;
    }
    if (anObject instanceof String) {   //兩個引用不等還會繼續(xù)比較
        String anotherString = (String)anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;  //字符串類是用字符數(shù)組實現(xiàn)的, 先要拿到兩個字符串的字符數(shù)組
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {  //然后對兩個數(shù)組逐個字符地進(jìn)行比較
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

  • 從上面的源碼可以看到, 當(dāng)調(diào)用String類型的equals()方法時, 首先會判斷兩個字符串的引用是否相等, 也就是說兩個字符串引用是否指向同一個對象, 是則返回true.
  • 如果不是指向同一個對象, 則把兩個字符串中的字符挨個進(jìn)行比較. 由于s1和s3字符串都是"hello", 是可以匹配成功的, 所以最終返回true.

深入探究equals(), 為什么會有equals()方法?

  • 通過上面的講解相信你已經(jīng)知道==和equals()的區(qū)別, 一個的比較規(guī)則是定死的, 一個是可以由編程人員自己定義的.

  • 可是為什么會有equals()方法, 而且還可以被自由定制呢?

  • 這個問題要落到Java語言的核心--面向?qū)ο笏枷肓? Java不同于面向過程的C語言, Java是一款面向?qū)ο蟮母呒壵Z言. 如果只是面向過程, 直接操作內(nèi)存上存儲的數(shù)據(jù)的話, 用==所定義的規(guī)則來判斷兩個數(shù)據(jù)是否相等已經(jīng)足夠了.

  • 而Java中處處是對象, 我們經(jīng)常要面對的問題是這兩個對象是否相等, 而不是這兩串二進(jìn)制數(shù)是否相等, 僅有"=="是完全不夠用的.

  • 考慮到編程人員會使用Java創(chuàng)建各種滿足它們業(yè)務(wù)需求的對象, 系統(tǒng)無法提前知道兩個對象在什么條件下算相等, Java干脆把判斷對象是否相等的權(quán)力交給編程人員.

  • 具體的措施是: 所有的類都必須繼承Object類, 而Object類中寫有equals()方法. 編程人員可以通過重寫equals()方法實現(xiàn)自己的比較策略, 也可以不重寫, 使用Object類的equals()比較策略.

//Object類中的equals()方法源碼
public boolean equals(Object obj) {
    return (this == obj);
}
  • 從Object類的equals()源碼可以看到, 如果編程人員沒有顯示地重寫equals()方法, 則該類對象默認(rèn)通過引用數(shù)據(jù)類型進(jìn)行比較, 也就是說比較兩個引用是否指向同一個對象.

補(bǔ)充: 關(guān)于基本數(shù)據(jù)類型包裝類的比較

由于Java中萬物皆對象, 就連基本數(shù)據(jù)類型也有其對應(yīng)的包裝對象, 那么它們對應(yīng)的比較策略是什么呢?

public static void main(String[] args) {
    int a = 3;
    Integer b = new Integer(3);
    System.out.println(b.equals(a));    //true, 自動裝箱
}

  • 從上面的代碼可以看到盡管兩個引用不同, 但是輸出的結(jié)果仍為true, 證明Integer包裝類重寫了equals()方法.
//Integer類中的equals方法
public boolean equals(Object obj) {
    if (obj instanceof Integer) {
        return value == ((Integer)obj).intValue();
    }
    return false;
}

  • 從源碼看到, 基本類型包裝類在重寫的equals方法中, 比較的還是基本數(shù)據(jù)類型的值.
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 注:都是在百度搜索整理的答案,如有侵權(quán)和錯誤,希告知更改。 一、哪些情況下的對象會被垃圾回收機(jī)制處理掉 ?當(dāng)對象對...
    Jenchar閱讀 3,309評論 3 2
  • 1、== java中的數(shù)據(jù)類型,可分為兩類: 1.基本數(shù)據(jù)類型,也稱原始數(shù)據(jù)類型 byte,short,char,...
    crush_d872閱讀 612評論 0 0
  • 1、== java中的數(shù)據(jù)類型,可分為兩類: 基本數(shù)據(jù)類型,也稱原始數(shù)據(jù)類型 byte,short,char,in...
    dlihasa閱讀 279評論 0 1
  • 設(shè)想這樣一個場景:早上被手機(jī)鬧鐘叫醒,懶懶地看了一眼手機(jī),睡眼朦朧之際有條新聞推送過來,是昨晚錯過的LOL比賽結(jié)果...
    Zander閱讀 571評論 0 4
  • 有一個問題困擾了我許久,人為什么要活著? 我想這個時代的人,少數(shù)的人活得明白,而大多數(shù)都人都不明白活著的意義但是...
    露從今夜閱讀 718評論 0 0

友情鏈接更多精彩內(nèi)容