2010年7月31日 星期六

[ Java 小學堂 ] Java 世界裡 equals 與 == 的差別


轉載自 這裡
前言 :
在Java裡,equals和==常令程式設計師困惑,這裡簡單說明如下 :
1. ==
測試物件參考時,唯有當兩個參考指向同一物件時,==運算子的結果才為true,同樣的,唯有當兩個參考指向不同物件時,!=運算子的結果才為true,這兩個運算子的處理與物件的內容無關。需要特別注意的是,在String中使用==,因為Java為節省記憶體,會在某一輪調區中維護唯一的String物件,所以如果在類別裡使用同一字串,Java只會建立一個唯一的字串而已。

2. equals
另一種測試的做法是equals,equals在類別為Java原先就存在時,是比較兩個物件是否為相同類型的類別後再比較其內容值是否相同,是就傳回true,否就傳回false。當要測試的類別是自定類別時,要依自定類別所提供的equals來決定如何比較,如果自定類別沒有覆蓋Object的equals類別的話,就以Object的equals來比較,Object的equals的比較方式如同==。

範例程式 :
下面以簡單的範例程式說明 equals 與 == 的差別 :
- myObject1.java 代碼 :
  1. package test;  
  2.   
  3. public class myObject1 {  
  4.      int nNum = 100;  
  5.        
  6.       public void setNum(int nN) {  
  7.         nNum = nN;  
  8.       }  
  9.        
  10.       public int getNum() {  
  11.         return nNum;  
  12.       }  
  13.        
  14.       public void printNum() {  
  15.         System.out.println(nNum);  
  16.       }  
  17. }  
- myObject2.java 代碼 :
  1. package test;  
  2.   
  3. public class myObject2 {  
  4.      int nNum = 100;  
  5.        
  6.       public void setNum(int nN) {  
  7.         nNum = nN;  
  8.       }  
  9.        
  10.       public int getNum() {  
  11.         return nNum;  
  12.       }  
  13.        
  14.       public void printNum() {  
  15.         System.out.println(nNum);  
  16.       }  
  17.        
  18.       public boolean equals(Object obj) {  
  19.         if (obj == nullreturn false;  
  20.         if (!(obj instanceof myObject2)) return false;  
  21.         return this.nNum == ((myObject2) obj).getNum();  
  22.       }  
  23. }  
- myEquals.java 代碼 :
  1. package test;  
  2.   
  3. public class myEquals {  
  4.   
  5.     public myEquals() {  
  6.         //字串型別  
  7.         String sA = "ABC";  
  8.         String sB = "ABC";  
  9.         String sC = new String("ABC");  
  10.        
  11.           //==的比較  
  12.         if (sA == sB)  
  13.           System.out.println("sA == sB (Because of String pool)");  
  14.         else  
  15.           System.out.println("sA != sB");  
  16.        
  17.         if (sA == sC)  
  18.           System.out.println("sA == sC");  
  19.         else  
  20.           System.out.println("sA != sC (Because sC uses new operator)");  
  21.        
  22.           //equals的比較  
  23.         if (sA.equals(sB))  
  24.           System.out.println("sA.equals(sB) = true (Because of the same value)");  
  25.         else  
  26.           System.out.println("sA.equals(sB) = false");  
  27.        
  28.         if (sA.equals(sC))  
  29.           System.out.println("sA.equals(sC) = true (Because of the same value)");  
  30.         else  
  31.           System.out.println("sA.equals(sC) = false");  
  32.        
  33.         //Java原有的型別  
  34.         Long lngA = new Long(100);  
  35.         Long lngB = new Long(100);  
  36.         Long lngC = new Long("100");  
  37.        
  38.           //==的比較  
  39.         if (lngA == lngB)  
  40.           System.out.println("lngA == lngB");  
  41.         else  
  42.           System.out.println("lngA != lngB (Because of the new operator)");  
  43.        
  44.         if (lngA == lngC)  
  45.           System.out.println("lngA == lngC");  
  46.         else  
  47.           System.out.println("lngA != lngC (Because of the new operator)");  
  48.        
  49.           //equals的比較  
  50.         if (lngA.equals(lngB))  
  51.           System.out.println("lngA.equals(lngB) = true (Same value)");  
  52.         else  
  53.           System.out.println("lngA.equals(lngB) = false");  
  54.        
  55.         if (lngA.equals(lngC))  
  56.           System.out.println("lngA.equals(lngC) = true (Same value)");  
  57.         else  
  58.           System.out.println("lngA.equals(lngC) = false");  
  59.        
  60.         //自定型別  
  61.         myObject1 m1A = new myObject1();  
  62.         myObject1 m1B = new myObject1();  
  63.         myObject2 m2A = new myObject2();  
  64.         myObject2 m2B = new myObject2();  
  65.        
  66.           //==的比較  
  67.         if (m1A == m1B)  
  68.           System.out.println("m1A == m1B");  
  69.         else  
  70.           System.out.println("m1A != m1B (Not same memory address)");  
  71.        
  72.         if (m2A == m2B)  
  73.           System.out.println("m2A == m2B");  
  74.         else  
  75.           System.out.println("m2A != m2B (Not same memory address)");  
  76.        
  77.           //equals的比較  
  78.         if (m1A.equals(m1B))  
  79.           System.out.println("m1A.equals(m1B) = true");  
  80.         else  
  81.           System.out.println("m1A.equals(m1B) = false (Not overwtire equals method)");  
  82.        
  83.         if (m2A.equals(m2B))  
  84.           System.out.println("m2A.equals(m2B) = true (Rewrite equals method)");  
  85.         else  
  86.           System.out.println("m2A.equals(m2B) = false");  
  87.       }  
  88.       public static void main(String[] args) {  
  89.         myEquals myEquals1 = new myEquals();  
  90.       }  
  91.   
  92. }  

執行結果 :
sA == sB (Because of String pool)
sA != sC (Because sC uses new operator)
sA.equals(sB) = true (Because of the same value)
sA.equals(sC) = true (Because of the same value)
lngA != lngB (Because of the new operator)
lngA != lngC (Because of the new operator)
lngA.equals(lngB) = true (Same value)
lngA.equals(lngC) = true (Same value)
m1A != m1B (Not same memory address)
m2A != m2B (Not same memory address)
m1A.equals(m1B) = false (Not overwtire equals method)
m2A.equals(m2B) = true (Rewrite equals method)

補充說明 :
This message was edited 2 times. Last update was at 03/12/2010 10:34:56

3 則留言:

  1. 有一段看不懂,想請教前輩:

    //自定型別
    myObject1 m1A = new myObject1();
    myObject1 m1B = new myObject1();
    myObject2 m2A = new myObject2();
    myObject2 m2B = new myObject2();

    //equals的比較
    if (m1A.equals(m1B))
    System.out.println("m1A.equals(m1B) = true");
    else
    System.out.println("m1A.equals(m1B) = false (Not overwtire equals method)");

    if (m2A.equals(m2B))
    System.out.println("m2A.equals(m2B) = true (Rewrite equals method)");
    else
    System.out.println("m2A.equals(m2B) = false");

    這段的結果:
    m1A.equals(m1B) = false (Not overwtire equals method)
    m2A.equals(m2B) = true (Rewrite equals method)

    看不懂m1A、m1B、m2A、m2B的差異,可以請你詳細說明一下嗎?

    回覆刪除
    回覆
    1. m1X (m1A, m1B) 類別並沒有改寫 equals(), 也就是使用預設 Object 的 equals(): 判斷是否為同一個物件.
      m2X (m2A, m2B) 類別改寫了 equals():
      1. if (obj == null) return false; 首先判斷輸入物件如果是 null 則返回 false
      2. if (!(obj instanceof myObject2)) return false; 接著判斷輸入物件是否是此物件類別延伸出來的物件, 不是就返回 false
      3. return this.nNum == ((myObject2) obj).getNum(); 最後判斷兩個物件的 field (nNum) 是否相等, 是就返回 true, 否則 false

      也就是說 m1A 的 equals() 是 Object 來的, 判斷兩個物件是否為同一個.
      因為 m1A 跟 m1B 不是同一個物件, 故 m1A.equals(m2B)=false

      而 m2A 與 m2B 都是 class myObject2 並改寫了 equals(). 故:
      1. m2B 不是 null -> 2. m2B 與 m2A 都是 class myObject2 -> 3. m2B 與 m2A 的 field (nNum) 相等.
      因此 m2A.equals(m2B) = true

      刪除
  2. Although an older version of Quick Luck, it continues to display high effectiveness in beating drug tests. Here is what you will find in the Sub Solution Synthetic Urine Kit: • 88 ml container • A vial of powdered urine • Temperature strip • 1 heat activator powder Pros: • One of the most reliable synthetic urine kits with a 17-year long track record • Undetectable biocide-free and toxins-free formula • It contains 13 chemical compounds with just the right amount of urea and uric acid • pH levels and specific gravity fall under the normal range • Heat activator powder provides a less-time consuming way to heat synthetic urine • Separate mixing container and urine vial are given to avoid cross-contamination Cons: • It does not come pre-mixed • There is no heating pad included in case the heat activator fails • Some may find the price to be a tad bit high Features: Unlike Quick Luck, Sub Solution is Clear Choice's powdered urine that needs to be mixed for use. It is an older product, but its concentration of urea, uric acid, and creatinine are on point. It contains all the 13 different chemicals that naturally occur in real human urine for normal pH levels and specific gravity. The Urinator is an electronic urine tester that uses only one pair of batteries to keep the temperature stable for at least four hours. The Urinator is a dependable and reusable device. Visit: https://www.urineworld.com/

    回覆刪除

[Git 常見問題] error: The following untracked working tree files would be overwritten by merge

  Source From  Here 方案1: // x -----删除忽略文件已经对 git 来说不识别的文件 // d -----删除未被添加到 git 的路径中的文件 // f -----强制运行 #   git clean -d -fx 方案2: 今天在服务器上  gi...