最近在項目中遇到一個問題,兩個值相同的Integer型值進行==比較時,發現Integer其中的一些奧秘,順便也複習一下==和equals的區別,先通過Damo代碼解釋如下:
System.out.println("<-128~127以內的Integer值,Integer x = value;的方式賦值。>");Integer i = 127;Integer j = 127;System.out.println("i=" + i + ",j =" + j);System.out.println("i == j:" + (i == j) + "<--比較-->i.equals(j):"+ i.equals(j));System.out.println("<-128~127以外的Integer值,Integer x = value;的方式賦值。>");Integer m = 128;Integer n = 128;System.out.println("m=" + m + ",n =" + n);System.out.println("m == n:" + (m == n) + "<--比較-->m.equals(n):"+ m.equals(n));System.out.println();System.out.println("<任意Integer值,Integer x = new Integer(value);的方式賦值。>");Integer x = new Integer(299);Integer y = new Integer(299);System.out.println("x=" + x + ",y =" + y);System.out.println("x == y:" + (x == y) + "<--比較-->x.equals(y):"+ x.equals(y));
輸出結果為:
<-128~127以內的Integer值,Integer x = value;的方式賦值。>i=127,j =127i == j:true<--比較-->i.equals(j):true<-128~127以外的Integer值,Integer x = value;的方式賦值。>m=128,n =128m == n:false<--比較-->m.equals(n):true<任意Integer值,Integer x = new Integer(value);的方式賦值。>x=299,y =299x == y:false<--比較-->x.equals(y):true
通過以上代碼及輸出結果,想必大家已經看出其中奧秘。先總結如下:
1、以上代碼第一段和第二段旨在說明:在-128~127的Integer值並且以Integer x = value;的方式賦值的Integer值在進行==和equals比較時,都會返回true,因為Java裡面對處在在-128~127之間的Integer值,用的是原生資料類型int,會在記憶體裡供重用,也就是說這之間的Integer值進行==比較時只是進行int原生資料類型的數值比較,而超出-128~127的範圍,進行==比較時是進行地址及數值比較。
2、第三段旨在說明:==和equals的區別,==是進行地址及值比較,無法對==操作符進行重載,而對於equals方法,Integer裡面的equals方法重寫了Object的equals方法,查看Integer源碼可以看出equals方法進行的是數值比較。
續詳解:
首先看一段代碼(使用JDK 5),如下: [html] view plain copy public class Hello { public static void main(String[] args) { int a = 1000, b = 1000; System.out.println(a == b); Integer c = 1000, d = 1000; System.out.println(c == d); Integer e = 100, f = 100; System.out.println(e == f); } }
輸出結果: [html] view plain copy true false true
The Java Language Specification, 3rd Edition 寫道: [html] view plain copy 為了節省記憶體,對於下列封裝對象的兩個執行個體,當它們的基本值相同時,他們總是==: Boolean Byte Character, \u0000 - \u007f(7f是十進位的127) Integer, -128 — 127
查看jdk源碼,如下: [java] view plain copy /** * Cache to support the object identity semantics of autoboxing for values between * -128 and 127 (inclusive) as required by JLS. * * The cache is initialized on first usage. During VM initialization the * getAndRemoveCacheProperties method may be used to get and remove any system * properites that configure the cache size. At this time, the size of the * cache may be controlled by the vm option -XX:AutoBoxCacheMax=<size>. */ // value of java.lang.Integer.IntegerCache.high property (obtained during VM init) private static String integerCacheHighPropValue; static void getAndRemoveCacheProperties() { if (!sun.misc.VM.isBooted()) { Properties props = System.getProperties(); integerCacheHighPropValue = (String)props.remove("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) System.setProperties(props); // remove from system props