Java核心 -- int和Integer
- Integer是int對應的包裝類 ,裡面有一個int型別的欄位儲存資料,並提供了基本的操作
- 在Java 5,引入了自動裝箱 和自動拆箱 (boxing/unboxing),Java可以根據上下文,自動進行轉換
-
在Java 5,還引入了值快取
(靜態工廠方法valueOf),預設快取範圍為-128 ~ 127
- Boolean,快取Boolean.TRUE/Boolean.FALSE
- Short,快取-128 ~ 127
- Byte,數值有限,全部快取
- Character,快取\u0000 ~ \u007F
自動裝箱 + 自動拆箱
Integer integer = 1; int unboxing = integer++;
1: invokestatic// Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 8: invokevirtual// Method java/lang/Integer.intValue:()I 11: iconst_1 12: iadd 13: invokestatic// Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 21: invokevirtual// Method java/lang/Integer.intValue:()I
- 自動裝箱和自動拆箱是一種語法糖 ,發生在編譯階段 (生成一致的位元組碼 )
- javac自動把裝箱 轉換為Integer.valueOf (可以利用值快取 機制),把拆箱 轉換為Integer.intValue
- 在效能敏感 的場合,要儘量避免無意中的自動裝箱和自動拆箱;但在大多數產品程式碼裡,還是以開發效率 優先
執行緒安全的計數器
原子類實現
// 簡單明瞭 public class Counter { private final AtomicLong counter = new AtomicLong(); public void increase() { counter.incrementAndGet(); } }
原始型別實現
// 複雜 public class CompactCounter { private volatile long counter; private static final AtomicLongFieldUpdater<CompactCounter> UPDATER = AtomicLongFieldUpdater.newUpdater(CompactCounter.class, "counter"); public void increase() { UPDATER.incrementAndGet(this); } }
不變類
private final int value;
BYTES
// Integer @Native public static final int SIZE = 32; public static final int BYTES = SIZE / Byte.SIZE; // Byte public static final int SIZE = 8;
原始型別的執行緒安全
- 原始型別的變數,需要使用併發相關手段,才能保證執行緒安全
- 如果有執行緒安全的計算需要,優先考慮AtomicInteger、AtomicLong 等執行緒安全類
- 部分比較寬的資料型別,如float、double ,都不能保證更新操作的原子性 (可能讀到只更新了一半資料位的數值)
侷限性
-
原始型別與Java泛型不能配合使用
- Java的泛型是偽泛型 ,屬於編譯期的技巧 ( 型別擦除+強制轉換 )
- 原始型別無法轉換為Object,因此無法與泛型配合使用
-
無法高效表達資料
- 原始型別陣列 ,在記憶體裡是一段連續的記憶體
- 引用型別陣列 ,儲存的是引用,實際的物件分散在堆裡,導致低效的資料操作 ,也無法充分利用CPU快取
轉載請註明出處:http://zhongmingmao.me/2019/05/04/java-core-int-Integer/
訪問原文「Java核心 -- int和Integer 」獲取最佳閱讀體驗並參與討論