什么是自動裝箱/自動拆箱?
Integer box = 321; int basic = box;
作為Java代碼中我們最常用到的一類語法糖
我們應當對其做一些“了解”
先上代碼,不妨先想一下它們的結果……
public class Demo01 { public static void main(String[] args) { Integer a = 1; Integer b = 2; Integer c = 3; Integer d = 3; Integer e = 321; Integer f = 321; Long g = 3L; System.out.println(c == d); System.out.println(Objects.equals(c, d)); System.out.println(e == f); System.out.println(c == (a+b)); System.out.println(c.equals(a+b)); System.out.println(g == (a+b)); System.out.println(g.equals(a+b)); } }
答案是:
true true false true true true false
作為程式員來講前五個,在這里就不做深究
重點是第五個與第六個
g == (a+b) // true g.equals((a+b)) // false
基礎好的同志可能已經看出了端倪:型別轉換
我們看一下編譯出來的Class檔案
當然,在這之前為了更方便查看,我們更改下它的原始碼格式:
boolean b1 = g == (a+b); System.out.println(b1);
使用IDEA查看這一段代碼:
boolean b1 = g == (long)(a + b); System.out.println(b1);
的確,通過型別轉換后,實際上是兩個 基礎資料型別long 在比較,通過位元組碼也可以看到他們的操作:
17: aload_3 18: invokevirtual #6 // Method java/lang/Long.longValue:()J 21: aload_1 22: invokevirtual #7 // Method java/lang/Integer.intValue:()I 25: aload_2 26: invokevirtual #7 // Method java/lang/Integer.intValue:()I 29: iadd 30: i2l 31: lcmp
那么第六段代碼又是如何得出false的呢?結合包裝類Long的原始碼與Class檔案中第六段代碼就可以得出結論:
public boolean equals(Object obj) { if (obj instanceof Long) { return value =https://www.cnblogs.com/wloppppped/archive/2021/04/15/= ((Long)obj).longValue(); } return false; }
boolean b2 = g.equals(a + b); System.out.println(b2);
前端編譯器并沒有“想當然”的為我們添加上型別轉換,畢竟型別比較是equals()的任務之一!(試想一下你重寫equals()的三大步驟???)
我們可以為其手動的添加型別轉換:
boolean b2 = g.equals((long)(a+b));
添加前后的位元組碼:
// 添加前
17: aload_3
18: aload_1 19: invokevirtual #6 // Method java/lang/Integer.intValue:()I 22: aload_2 23: invokevirtual #6 // Method java/lang/Integer.intValue:()I 26: iadd 27: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 30: invokevirtual #7 // Method java/lang/Long.equals:(Ljava/lang/Object;)Z
// 添加后 18: aload_1 19: invokevirtual #6 // Method java/lang/Integer.intValue:()I 22: aload_2 23: invokevirtual #6 // Method java/lang/Integer.intValue:()I 26: iadd 27: i2l 28: invokestatic #5 // Method java/lang/Long.valueOf:(J)Ljava/lang/Long; 31: invokevirtual #7 // Method java/lang/Long.equals:(Ljava/lang/Object;)Z
在計數器27處新增了 i2l 型別轉換
實作了我們“想當然”的結果:
true
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/276569.html
標籤:其他
下一篇:JAVA多執行緒之執行緒池
