這次遇到一個簡單到不行的 Java 小地雷,

實作物件的 equals() 時, 若要比對 non-primitive typeInteger, Long, Double 等物件數值,

請記得使用 equals() 不要用 == ,

或者自己將 Integer.intValue()Long.longValue() 拿出來再用 ==

不然 boolean eq = new Integer(1) == new Integer(1) 會永遠給你 false,

除非夠幸運兩個 Object 發生 conflict XD

這是 Integer.equals(obj) 的實作, 也就是為什麼 equals(obj) 才會正確的原因
private final int value; public boolean equals(Object obj) { if (obj instanceof Integer) { return value == ((Integer)obj).intValue(); } return false; }

參考資料

另外參考了 stackoverflow Compare non-primitive Long values 127 and 128 後, 發現 -128127 之間的數值 jvm 會先 cache 起來 ,

如下程式碼:

        Long a = Long .valueOf(127);
        Long b = Long .valueOf(127);
        boolean eq = a == b; // 是 true
        Long a = Long .valueOf(128);
        Long b = Long .valueOf(128);
        boolean eq = a == b; // 是 false

        boolean eq = new Long(1) == new Long(1); // 但這一樣永遠是 false !

小結論:

  1. == 去比較 new Long(long) 的數值都不會相等,
  2. == 去比較 Long.valueOf(long) 的數值只有在 -128 到 127 之間會相等
  3. 所以若要比較 non-primitive type (ex: Integer, Long, Double) 的數值, 請用 equals(obj)