今天在和同事討論問題的時候,無心間談到了Integer對象的比較,先看下代碼:java
package test; public class IntegerEqual { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Integer a = 1; Integer b = 1; Integer c = 2000; Integer d = 2000; System.out.println(a==b); System.out.println(c==d); } }
相信不少人一看到這段代碼,就會感受輸出的結果是true,true;實際上這段代碼的輸出結果是true,false;這是爲何呢?一樣的對象爲何比較的結果不同呢?緩存
先來分析下Integer a=1;的實現方式,1是數字是怎麼放到Integer這個對象中去的;咱們知道這是JDK5新增的語法自動裝箱和拆箱功能實現的,但是具體的這個裝箱功能室如何實現的呢?咱們先來看下Integer.valueOf()這個方法,由於這是Integer默認的裝箱的實現方式:ui
/** * Returns a <tt>Integer</tt> instance representing the specified * <tt>int</tt> value. * If a new <tt>Integer</tt> instance is not required, this method * should generally be used in preference to the constructor * {@link #Integer(int)}, as this method is likely to yield * significantly better space and time performance by caching * frequently requested values. * * @param i an <code>int</code> value. * @return a <tt>Integer</tt> instance representing <tt>i</tt>. * @since 1.5 */ public static Integer valueOf(int i) { if(i >= -128 && i <= IntegerCache.high) return IntegerCache.cache[i + 128]; else return new Integer(i); }
經過註釋也能夠發現,這是JDK5的時候新增的方法,先來簡單分析下這個方法具體作了什麼事情;原來她內部維護了一個緩存池,它老是Integer緩存池中獲取Integer對象,超出了其緩存池緩存池(-128到127),它才new新的Integer對象。只要在這個範圍內,都是直接取出對象而不是建立,因此值老是相等的,可是若是超過了這個範圍,那麼它就會穿件新的對象(-2147483648到-128和127到2147483647)(Integer.MAX_VALUE:2147483647,Integer.MIN_VALUE:-2147483648),一旦是建立的對象,那麼比較的是對象天然是不相等,即便值是相等的。this
public boolean equals(Object obj) { if (obj instanceof Integer) { return value == ((Integer)obj).intValue(); } return false; }
由於這個方法取得是具體的值,因此無論是多少,具體的結果老是相等的。spa