《深入理解Java虛擬機器》中講文法糖時,提到了下面這個例子(不是原文中的例子,我自己改過):
public class AutoBoxingTest {/** * @param args */public static void main(String[] args) {Integer a = 1;Integer b = 2;Integer c = 127;Integer d = 127;Integer e = 3;Integer f = 3;Long g = 3L;System.out.println(c == d); System.out.println(e == f);System.out.println(e == (a + b));System.out.println(e.equals(a + b));System.out.println(g == (a + b));System.out.println(g.equals(a + b));}}
輸出結果:
true
true
true
true
true
false
使用JAD反編譯後,結果:
import java.io.PrintStream;public class AutoBoxingTest{ public AutoBoxingTest() { // 0 0:aload_0 // 1 1:invokespecial #1 <Method void Object()> // 2 4:return } public static void main(String args[]) { Integer integer = Integer.valueOf(1); // 0 0:iconst_1 // 1 1:invokestatic #2 <Method Integer Integer.valueOf(int)> // 2 4:astore_1 Integer integer1 = Integer.valueOf(2); // 3 5:iconst_2 // 4 6:invokestatic #2 <Method Integer Integer.valueOf(int)> // 5 9:astore_2 Integer integer2 = Integer.valueOf(127); // 6 10:bipush 127 // 7 12:invokestatic #2 <Method Integer Integer.valueOf(int)> // 8 15:astore_3 Integer integer3 = Integer.valueOf(127); // 9 16:bipush 127 // 10 18:invokestatic #2 <Method Integer Integer.valueOf(int)> // 11 21:astore 4 Integer integer4 = Integer.valueOf(3); // 12 23:iconst_3 // 13 24:invokestatic #2 <Method Integer Integer.valueOf(int)> // 14 27:astore 5 Integer integer5 = Integer.valueOf(3); // 15 29:iconst_3 // 16 30:invokestatic #2 <Method Integer Integer.valueOf(int)> // 17 33:astore 6 Long long1 = Long.valueOf(3L); // 18 35:ldc2w #3 <Long 3L> // 19 38:invokestatic #5 <Method Long Long.valueOf(long)> // 20 41:astore 7 System.out.println(integer2 == integer3); // 21 43:getstatic #6 <Field PrintStream System.out> // 22 46:aload_3 // 23 47:aload 4 // 24 49:if_acmpne 56 // 25 52:iconst_1 // 26 53:goto 57 // 27 56:iconst_0 // 28 57:invokevirtual #7 <Method void PrintStream.println(boolean)> System.out.println(integer4 == integer5); // 29 60:getstatic #6 <Field PrintStream System.out> // 30 63:aload 5 // 31 65:aload 6 // 32 67:if_acmpne 74 // 33 70:iconst_1 // 34 71:goto 75 // 35 74:iconst_0 // 36 75:invokevirtual #7 <Method void PrintStream.println(boolean)> System.out.println(integer4.intValue() == integer.intValue() + integer1.intValue()); // 37 78:getstatic #6 <Field PrintStream System.out> // 38 81:aload 5 // 39 83:invokevirtual #8 <Method int Integer.intValue()> // 40 86:aload_1 // 41 87:invokevirtual #8 <Method int Integer.intValue()> // 42 90:aload_2 // 43 91:invokevirtual #8 <Method int Integer.intValue()> // 44 94:iadd // 45 95:icmpne 102 // 46 98:iconst_1 // 47 99:goto 103 // 48 102:iconst_0 // 49 103:invokevirtual #7 <Method void PrintStream.println(boolean)> System.out.println(integer4.equals(Integer.valueOf(integer.intValue() + integer1.intValue()))); // 50 106:getstatic #6 <Field PrintStream System.out> // 51 109:aload 5 // 52 111:aload_1 // 53 112:invokevirtual #8 <Method int Integer.intValue()> // 54 115:aload_2 // 55 116:invokevirtual #8 <Method int Integer.intValue()> // 56 119:iadd // 57 120:invokestatic #2 <Method Integer Integer.valueOf(int)> // 58 123:invokevirtual #9 <Method boolean Integer.equals(Object)> // 59 126:invokevirtual #7 <Method void PrintStream.println(boolean)> System.out.println(long1.longValue() == (long)(integer.intValue() + integer1.intValue())); // 60 129:getstatic #6 <Field PrintStream System.out> // 61 132:aload 7 // 62 134:invokevirtual #10 <Method long Long.longValue()> // 63 137:aload_1 // 64 138:invokevirtual #8 <Method int Integer.intValue()> // 65 141:aload_2 // 66 142:invokevirtual #8 <Method int Integer.intValue()> // 67 145:iadd // 68 146:i2l // 69 147:lcmp // 70 148:ifne 155 // 71 151:iconst_1 // 72 152:goto 156 // 73 155:iconst_0 // 74 156:invokevirtual #7 <Method void PrintStream.println(boolean)> System.out.println(long1.equals(Integer.valueOf(integer.intValue() + integer1.intValue()))); // 75 159:getstatic #6 <Field PrintStream System.out> // 76 162:aload 7 // 77 164:aload_1 // 78 165:invokevirtual #8 <Method int Integer.intValue()> // 79 168:aload_2 // 80 169:invokevirtual #8 <Method int Integer.intValue()> // 81 172:iadd // 82 173:invokestatic #2 <Method Integer Integer.valueOf(int)> // 83 176:invokevirtual #11 <Method boolean Long.equals(Object)> // 84 179:invokevirtual #7 <Method void PrintStream.println(boolean)> // 85 182:return }}
從中可以看出,最後false產生的原因是Long類型和Integer進行比較,不同類型自然不會equal了。
另外,原文中使用的是321而不是127,這樣做java的位元組碼中將使用sipush而不是bipush,此時==判斷會變為false,目前我不太明白為啥會這樣,望大神指點。