首頁 Java java教程 淺談Java中的equals和==

淺談Java中的equals和==

Dec 16, 2016 am 09:18 AM
equals

在初學Java時,可能會常常碰到下面的程式碼:

String str1 = new String("hello");
String str2 = new String("hello");
        
System.out.println(str1==str2);
System.out.println(str1.equals(str2));
登入後複製

  為什麼第4行和第5行的輸出結果不一樣? ==和equals方法之間的差異是什麼?如果在初學Java的時候這個問題不弄清楚,就會導致自己在以後寫程式碼時出現一些低階的錯誤。今天就來一起了解==和equals方法的差別。

一.關係操作符「==」到底比較的是什麼?

  下面這個句話是摘自《Java程式設計思想》一書中的原話:

  「關係運算子產生的是一個boolean結果,它們計算的是操作數的值之間的關係」。

  這句話看似簡單,理解起來還是需要細細體會的。說的簡單點,==就是用來比較值是否相等。以下先看幾個例子:

public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        
        int n=3;
        int m=3;
        
        System.out.println(n==m);
        
        String str = new String("hello");
        String str1 = new String("hello");
        String str2 = new String("hello");
        
        System.out.println(str1==str2);
        
        str1 = str;
        str2 = str;
        System.out.println(str1==str2);
    }

}
登入後複製

  輸出結果為 true false true

  n==m結果為true,這個很容易理解,變數n和變數m儲存的值都為3,肯定是相等的。而為什麼str1和str2兩次比較的結果不同?要理解這個其實只需要理解基本資料型態變數和非基本資料型別變數的差異。

  在Java中游8種基本資料型別:

  浮點型:float(4 byte), double(8 byte)

  , long(8 byte)

  字符型: char(2 byte)

  布爾型: boolean(JVM規範沒有明確規定其所佔的空間大小,僅規定其只能夠取字面值"true"和"false" )

  對於這8種基本資料類型的變量,變數直接儲存的是“值”,因此在用關係運算元==來進行比較時,比較的就是 “值” 本身。要注意浮點型和整型都是有符號類型的,而char是無符號型的(char型別取值範圍為0~2^16-1).

  也就是說例如:

  int n= 3;

  int m=3; 

  變數n和變數m都是直接儲存的"3"這個數值,所以用==比較的時候結果是true。

  而對於非基本資料類型的變量,在一些書籍中稱為 引用類型的變數。例如上面的str1就是引用型別的變量,引用類型的變數儲存的並不是 「值」本身,而是於其關聯的物件在記憶體中的位址。例如下面這行程式碼:

  String str1;

  這句話宣告了一個引用型別的變量,此時它並沒有和任何物件關聯。

  而透過new String("hello")產生一個物件(也稱為作為類別String的實例),並將這個物件和str1綁定:

  str1= new String("hello");那麼str1指向了一個物件(很多地方也把str1稱為物件的引用),此時變數str1中儲存的是它指向的物件在記憶體中的儲存位址,並不是「值」本身,也就是說並不是直接儲存的字串"hello"。這裡面的引用和C/C++中的指標很類似。

  因此在用==對str1和str2進行第一次比較時,得到的結果是false。因此它們分別指向的是不同的對象,也就是說它們實際儲存的記憶體位址不同。

  而在第二次比較時,都讓str1和str2指向了str指向的對象,那麼得到的結果毫無疑問是true。

二.equals比較的又是什麼?

  equals方法是基底類別Object中的方法,因此對於所有的繼承於Object的類別都會有該方法。為了更直觀地理解equals方法的作用,直接看Object類別中equals方法的實作。

  該類別的源碼路徑為:C:Program FilesJavajdk1.6.0_14的src.zip 的java.lang路徑下的Object.java(視個人jdk安裝路徑而定)。

  以下是Object類別中equals方法的實作:

淺談Java中的equals和==  很顯然,在Object類別中,equals方法是用來比較兩個物件的參考是否相等,即是否指向同一個物件。

  但是有些朋友又會有疑問了,為什麼下面一段程式碼的輸出結果是true?

public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        
        String str1 = new String("hello");
        String str2 = new String("hello");
        
        System.out.println(str1.equals(str2));
    }
}
登入後複製

  要知道究竟,可以看一下String類別的equals方法的具體實現,同樣在該路徑下,String.java為String類別的實作。

  以下是String類別中equals方法的具體實作:

淺談Java中的equals和==  可以看出,String類別對equals方法進行了重寫,用來比較指向的物件所儲存的字串是否相等。

  其他的一些類別諸如Double,Date,Integer等,都對equals方法進行了重寫用來比較指向的物件所儲存的內容是否相等。

  總結來說:

  1)對於==,如果作用於基本資料類型的變量,則直接比較其儲存的「值」是否相等;

    如果作用於引用類型的變量,則比較的是所指向的物件的位址

2)對於equals方法,注意:equals方法不能作用於基本資料型別的變數

    如果沒有對equals方法進行重寫,則比較的是引用型別的變數所指向的物件的位址;

 等類別對equals方法進行了重寫的話,比較的是所指向的物件的內容。




更多淺談Java中的equals和==相關文章請關注PHP中文網!


本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前 By 尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

2025年的前4個JavaScript框架:React,Angular,Vue,Svelte 2025年的前4個JavaScript框架:React,Angular,Vue,Svelte Mar 07, 2025 pm 06:09 PM

2025年的前4個JavaScript框架:React,Angular,Vue,Svelte

如何使用咖啡因或Guava Cache等庫在Java應用程序中實現多層緩存? 如何使用咖啡因或Guava Cache等庫在Java應用程序中實現多層緩存? Mar 17, 2025 pm 05:44 PM

如何使用咖啡因或Guava Cache等庫在Java應用程序中實現多層緩存?

Node.js 20:關鍵性能提升和新功能 Node.js 20:關鍵性能提升和新功能 Mar 07, 2025 pm 06:12 PM

Node.js 20:關鍵性能提升和新功能

Java的類負載機制如何起作用,包括不同的類載荷及其委託模型? Java的類負載機制如何起作用,包括不同的類載荷及其委託模型? Mar 17, 2025 pm 05:35 PM

Java的類負載機制如何起作用,包括不同的類載荷及其委託模型?

冰山:數據湖桌的未來 冰山:數據湖桌的未來 Mar 07, 2025 pm 06:31 PM

冰山:數據湖桌的未來

Spring Boot Snakeyaml 2.0 CVE-2022-1471問題已修復 Spring Boot Snakeyaml 2.0 CVE-2022-1471問題已修復 Mar 07, 2025 pm 05:52 PM

Spring Boot Snakeyaml 2.0 CVE-2022-1471問題已修復

如何將JPA(Java持久性API)用於具有高級功能(例如緩存和懶惰加載)的對象相關映射? 如何將JPA(Java持久性API)用於具有高級功能(例如緩存和懶惰加載)的對象相關映射? Mar 17, 2025 pm 05:43 PM

如何將JPA(Java持久性API)用於具有高級功能(例如緩存和懶惰加載)的對象相關映射?

如何將Maven或Gradle用於高級Java項目管理,構建自動化和依賴性解決方案? 如何將Maven或Gradle用於高級Java項目管理,構建自動化和依賴性解決方案? Mar 17, 2025 pm 05:46 PM

如何將Maven或Gradle用於高級Java項目管理,構建自動化和依賴性解決方案?

See all articles