1. 程式人生 > >淺談Java中的equals和==(轉)

淺談Java中的equals和==(轉)

本文轉自:https://www.cnblogs.com/dolphin0520/p/3592500.html

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

1 String str1 = new String("hello");
2 String str2 = new String("hello");
3         
4 System.out.println(str1==str2);
5 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)

  整型:byte(1 byte), short(2 byte), int(4 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 Files\Java\jdk1.6.0_14的src.zip 的java.lang路徑下的Object.java(視個人jdk安裝路徑而定)。

  下面是Object類中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方法的具體實現:

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

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

  總結來說:

  1)對於==,如果作用於基本資料型別的變數,則直接比較其儲存的 “值”是否相等;

    如果作用於引用型別的變數,則比較的是所指向的物件的地址

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

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

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

相關推薦

JAVA物件的理解

   我們知道程式語言是一個幫助我們和計算機“對話”的工具,我們可以通過它去讓計算機做一些事。而JAVA語言又是其中的高階語言,那麼什麼是高階?機器語言和人類語言之間有著巨大的鴻溝,人們不斷的想要跨過這個鴻溝,在這個過程中出現了一些“工具”,就是所謂的程式語言。通過這些語言

javareplace()replaceAll()的區別

replace和replaceAll是JAVA中常用的替換字元的方法,它們的區別是: 1)replace的引數是char和CharSequence,即可以支援字元的替換,也支援字串的替換(CharSequence即字串序列的意思,說白了也就是字串); 2)replaceA

Javaequals==()

本文轉自:https://www.cnblogs.com/dolphin0520/p/3592500.html 在初學Java時,可能會經常碰到下面的程式碼: 1 String str1 = new String("hello"); 2 String str2 = new String("hel

java筆記】Javaequals==

在初學Java時,可能會經常碰到下面的程式碼: String str1 = new String("hello"); String str2 = new String("hello"); System.out.println(str1==str2); System.out.

Java物件的==、equalshashCode

目錄 運算子 == equals() String中的equals() Integer中的equals() Long中equals() hashCode() 運算子 == Java中的==是比較兩

Java的深拷貝拷貝

detail tle pac err @override 復制對象 deep har 間接   淺談Java中的深拷貝和淺拷貝(轉載) 原文鏈接: http://blog.csdn.net/tounaobun/article/details/8491392 假如說你想復制一

java的"=="eqals區別

short copy 覆寫 main 否則 變量 程序 bar gif 在初學Java時,可能會經常碰到下面的代碼: 1 String str1 = new String("hello"); 2 String str2 = new String("hello");

Java的物件物件的引用

淺談java中的物件和引用 文章轉載出處:https://www.cnblogs.com/dolphin0520/p/3592498.html 在Java中,有一組名詞經常一起出現,它們就是“物件和物件引用”,很多朋友在初學Java的時候可能經常會混淆這2個概念,覺得它們是一回事,事

Java的物件引用

Java物件及其引用  原文:http://zwmf.iteye.com/blog/1738574 關於物件與引用之間的一些基本概念。         初學Java時,在很長一段時間裡,總覺得基本概念很模糊。後來才知道,在許多Java書中,把物件和物件的引用混為一談。可是,

java"&&""&"的區別

“&&”和”&”都是java中的邏輯運算子,並且它們都表示“邏輯與”即“同真則真,有一假則假”,它們的區別在於”&&”具有短路功能,即如果左邊是false,則右邊的邏輯表示式不會執行。而”&”沒有短路功能,無論左邊是false還是true右邊都會執行。

java的值型別引用型別

1、值型別 (1)也就是基本的資料型別分為:四類八種 (2)四類:整型、浮點型、字元型、布林型 (3)八種:整型4種--byte、short、int、long              浮點型2種--float、double    字元型:char        

javaOO的概念設計原則(必看)

一.OO(面向物件)的設計基礎 面向物件(OO):就是基於物件概念,以物件為中心,以類和繼承為構造機制,充分利用介面和多型提供靈活性,來認識、理解、刻劃客觀世界和設計、構建相應的軟體系統。面向物件的特徵:雖然各種面向物件程式語言相互有別,但都能看到它們對面向物件基本特徵的支援, 即 “抽象、

java拷貝(複製)深拷貝(深複製)

淺拷貝: 淺拷貝又稱為淺複製,淺克隆,淺拷貝是指拷貝時只拷貝物件本身(包括物件中的基本變數),而不拷貝物件包含的引用所指向的物件,拷貝出來的物件的所有變數的值都含有與原來物件相同的值,而所有對其他物件的引用都指向原來的物件,簡單地說,淺拷貝只拷貝物件不拷貝引用

Java如何將字串成Json物件以及從Json物件獲得相應的值

前序:在做專案的過程中有次需要將json格式的字元拼接起來作為HTTP請求的一部分,且伺服器響應資訊即收到的返回資訊也是json格式的字串,在做這個專案中請求資訊我是使用字串拼接的,長長的json格式字串讓我拼接了半天,中途出現了幾次錯誤,白白耗費了時間。解析響應的json格

Java的棧

== 寫在前面 首地址 n) char 即使 作用 ble 堆和棧 人們常說堆棧堆棧,堆和棧是內存中兩處不一樣的地方,什麽樣的數據存在棧,又是什麽樣的數據存在堆中? 這裏淺談Java中的棧和堆 首先,將結論寫在前面,後面再用例子加以驗證。 Java的棧中存儲以下類型數據

Java的hashCode方法

implement state ask get() 存在 rsa key 沖突 如何 哈希表這個數據結構想必大多數人都不陌生,而且在很多地方都會利用到hash表來提高查找效率。在Java的Object類中有一個方法: public native int hashCode(

java內置的觀察者模式與動態代理的實現

所有 代理 notify play ani effect 一個 indicate protected 一.關於觀察者模式 1.將觀察者與被觀察者分離開來,當被觀察者發生變化時,將通知所有觀察者,觀察者會根據這些變化做出對應的處理。 2.jdk裏已經提供對應的Observer

Mybatis的 ${ } #{ }的區別

mybatis sql註入 語句 nbsp 之前 com pre 預編譯 sql 語句 一、舉例說明 1 select * from user where name = "dato"; 2 3 select * from user where name = #

JAVA“增強”類的某個方法的幾個方法!

exc 目標 byte 相同 nbsp 優點 method value oca 一、繼承 使用場景:能夠控制這個類的構造的時候,才可以使用繼承。  優點:簡單容易使用, 缺點:耦合性大大的增強,不利於後期的維護,所以對於繼承這種方法,謹慎使用。 代碼實現:二、裝飾者模式 

JAVA字符串常量的儲存位置

數據 每一個 [] jit 返回 inf post 符號 boolean 在講述這些之前我們需要一些預備知識: Java的內存結構我們可以通過兩個方面去看待它。 一、從抽象的JVM的角度去看。相關定義請參考JVM規範:Chapter 2. The Structure o