從java equals和==說起

來源:互聯網
上載者:User

程式運行時,對象時怎麼進行放置安排的?特別記憶體是怎麼分配的?對於這方面的瞭解對我們理解程式的運行有很大的協助。有五個地方可以儲存資料:

1》儲存空間。這是最快的儲存區,因為它位於不同於其他儲存區的地方——處理器內部。但是寄存器的數量極其有限,所以寄存器根據需求進行分配。

2》堆棧。堆棧簡稱棧(stack),位於通用RAM,但通過堆棧指標可以從處理器那裡獲得直接支援。堆棧指標若向下移動,則分配新的記憶體;若向上移動,則釋放那些記憶體。這是一種快速有效分配儲存方式,僅次於寄存器。java的對象引用就儲存於堆棧中

3》堆(heap)。一種通用的記憶體池(也存在於RMA中),用於存放java對象。堆不同於棧的好處是:編譯器不需要知道儲存的資料在堆裡存活多長時間。因此,在堆裡分配儲存有很大的靈活性。當需要一個對象時,只需要new寫一行簡單的代碼,當執行這行代碼時,會自動在堆裡進行儲存分配。用堆進行儲存分配和清理可能比用棧進行儲存分配需要更多的時間。

4》常量儲存。常量值通常直接存放在程式碼內部,這樣做是安全的,因為他們永遠不會被改變。

5》非RMA儲存。如果資料完全存活於程式之外,那麼它可能不受程式任何控制,在程式沒有執行時也可以存在。其中兩個基本的例子是流對象和持久對象。在流對象中,兌現轉化為位元組流,通常被發送給另一台機器。在“持久化對象”中,對象被存放於磁碟上,因此,即使終止程式,它們人可以保持自己的狀態。這種儲存方式的技巧在於:把對象轉化成可以存放在其他媒介上的事物,在需要時,可以回複成常規的,基於RMA的對象。java提供了對輕量級持久化的支援,而諸如jdbc和hibernate這樣的機制提供了更加複雜的對在資料庫中儲存和讀取對象資訊的支援。

以上幾個概念主要摘自《Thinking In Java》,個人覺得對於上述幾個概念的理解可以協助我們更好的區分equals和==,下面說說兩者的關係:

==操作符專門用來比較兩個變數的值是否相等,也就是用於比較變數所對應的記憶體中所儲存的數值是否相同,要比較兩個基本類型的資料或兩個參考型別的資料或兩個引用變數是否相等,只能用==操作符。

如果一個變數指向的資料是物件類型的,那麼這時涉及了兩塊記憶體,對象本身佔用一塊記憶體(堆記憶體),變數本身(這裡即對象的引用)也佔用一塊記憶體(棧記憶體),例如Object obj = new Object();變數obj時一塊記憶體,new Object()是一個記憶體,此時,變數所對應的記憶體中儲存的數值就是對象佔用的那塊記憶體的首地址。對於指向物件類型變數,如果要比較兩個變數是夠指向同一個對象,即要看這兩個變數所對應的記憶體中的數值是否相等,這時候需要用==操作符進行比較。

equals方法適用於比較兩個獨立對象的內容是否相同,就好比去比較兩個人的長相是否相同,它比較的兩個對象時獨立的。

簡單的說就是:

==操作比較的是兩個變數的值是否相等,對於引用型變數表示的是兩個變數在堆中儲存的地址是否相同,即棧中的內容是否相同。

equals動作表示的兩個變數是否是對同一個對象的引用,即堆中的內容是否相同。

==比較的是2個對象的地址,而equals比較的是2個對象的內容。

下面看幾個例子:

一、String中的equals和==1、public class TestString {     public static void main(String[] args) {         String s1 = "Monday";         String s2 = "Monday";     }}上面這段程式中,到底有幾個對象呢?來檢測一下吧,稍微改動一下程式public class TestString {     public static void main(String[] args) {         String s1 = "Monday";         String s2 = "Monday";         if (s1 == s2)             System.out.println("s1 == s2");         else             System.out.println("s1 != s2");     }}編譯並運行程式,輸出:s1 == s2說明:s1 與 s2 引用同一個 String 對象 -- "Monday"!2.再稍微改動一下程式,會有更奇怪的發現:public class TestString {     public static void main(String[] args) {         String s1 = "Monday";         String s2 = new String("Monday");         if (s1 == s2)             System.out.println("s1 == s2");         else             System.out.println("s1 != s2");         if (s1.equals(s2))             System.out.println("s1 equals s2");         else             System.out.println("s1 not equals s2");     }}我們將 s2 用 new 操作符建立程式輸出:s1 != s2s1 equals s2說明:s1 s2分別引用了兩個"Monday"String對象3. 字串緩衝池原來,程式在啟動並執行時候會建立一個字串緩衝池當使用 s2 = "Monday" 這樣的表達是建立字串的時候,程式首先會在這個String緩衝池中尋找相同值的對象,在第一個程式中,s1先被放到了池中,所以在s2被建立的時候,程式找到了具有相同值的 s1將 s2 引用 s1 所引用的對象"Monday"第二段程式中,使用了 new 操作符,他明白的告訴程式:"我要一個新的!不要舊的!"於是一個新的"Monday"Sting對象被建立在記憶體中。他們的值相同,但是位置不同,一個在池中遊泳一個在岸邊休息。哎呀,真是資源浪費,明明是一樣的非要分開做什麼呢?4. 再次更改程式:public class TestString {     public static void main(String[] args) {         String s1 = "Monday";         String s2 = new String("Monday");         s2 = s2.intern();         if (s1 == s2)             System.out.println("s1 == s2");         else             System.out.println("s1 != s2");         if (s1.equals(s2))             System.out.println("s1 equals s2");         else             System.out.println("s1 not equals s2");     }}這次加入:s2 = s2.intern();程式輸出:s1 == s2s1 equals s2原來,(java.lang.String的intern()方法 "abc".intern()方法的傳回值還是字串"abc",表面上看起來好像這個方法沒什麼用處。但實際上,它做了個小動作: 檢查字串池裡是否存在"abc"這麼一個字串,如果存在,就返回池裡的字串;如果不存在,該方法會把"abc"添加到字串池中,然後再返回它的引用。)更好的辦法:把所有的String都intern()到緩衝池去吧最好在用到new的時候就進行這個操作String s2 = new String("Monday").intern();然後就可以用==比較兩個字串的值了二、單一資料型別和封裝類中的equals和==Java為每一個單一資料型別提供了一個封裝類,每個基礎資料型別 (Elementary Data Type)可以封裝成物件類型。 除int(Integer)和char(Character),其餘類型首字母大寫即成封裝類類型名。double (Double), float(Float),long(Long), short(Short),byte(Byte),boolean(Boolean).  以int和Integer為例說明 Java中int和Integer區別如下:1.int是基本的資料類型,預設值可以為0;2.Integer是int的封裝類,預設值為null;3.int和Integer都可以表示某一個數值;4.int和Integer不能夠互用,因為他們兩種不同的資料類型;int a1=1;int a2=1;Integer b1 =new Integer (1);Integer b2 =new Integer (1);------------------------------a1==a2 這個是成立的,很簡單,都知道a1==b1 這個是不成立的.運算式的值為 false ,它們是不同的資料類型(在jdk1.5以上版本中為true)b1==b2 這個也是不成立的.運算式的值為 false,雖然是相同的資料類型,但是它們是兩個對象,==比較的是2個對象的地址,它們的地址是不相等的,內容相等都是1;b1.equals(b2)==true 這個是成立的,運算式的值為 true. 相同資料類型,兩個對象,地址不同,內容相同, quals比較的是2個對象的內容,所以成立。(a.equals(b),因為equals比較的是兩個對象,所以a,b都不能為基礎資料型別 (Elementary Data Type),否則會出編譯錯誤。)(在jdk1.5以上版本中,b可以為基礎資料型別 (Elementary Data Type),a不可以)同理,其它的封裝類和基本類型也是這樣的.java中equals和==的區別==比較的是2個對象的地址,而equals比較的是2個對象的內容。在jdk1.5以上的版本中,基本類型和封裝類能自動轉化,與String類型的對象和字串常量類似。        Integer i1 = 123;        Integer i2 = 123;                int i = 123;                Integer i3 = new Integer(123);        Integer i4 = new Integer(123);                               System.out.println("i1 == i2 = "+(i1 == i2));        System.out.println("i1.equals(i2) = "+(i1.equals(i2)));                System.out.println();        System.out.println("i3 == i4 = "+(i3 == i4));        System.out.println("i3.equals(i4) = "+(i3.equals(i4)));                System.out.println();        System.out.println("i2 == i4 = "+(i2 == i4));        System.out.println("i2.equals(i4) = "+(i2.equals(i4)));                System.out.println();        System.out.println("i == i2 = "+(i == i2));        System.out.println("i1.equals(i) = "+(i1.equals(i)));                System.out.println();        System.out.println("i == i4 = "+(i == i4));        System.out.println("i4.equals(i) = "+(i4.equals(i)));        ------------------------------        i1 == i2 = true      i1.equals(i2) = true      i3 == i4 = false      i3.equals(i4) = true      i2 == i4 = false      i2.equals(i4) = true      i == i2 = true      i1.equals(i) = true      i == i4 = true      i4.equals(i) = true


至於很多地方提到過的hashcode的概念,個人覺得比較難於理解,在這裡就先不予討論了。等自己真正理解這一塊的時候再做比較。百度文庫中有篇文中說得比較全面,貼出連結以供參考http://wenku.baidu.com/view/2d25e10d4a7302768e9939d7.html

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.