5、使用原始類型和棧
之前介紹了來自 jOOQ的例子中使用了大量的泛型,導緻的結果是使用了 byte、 short、 int 和 long 的包裝類。但至少泛型在Java 10或者Valhalla項目中被專門化之前,不應該成為代碼的限制。因為可以通過下面的方法來進行替換:
//存儲在堆上
Integer i = 817598;
……如果這樣寫的話:
// 存儲在棧上
int i = 817598;
在使用數組時情況可能會變得更加糟糕:
//在堆上生成了三個對象
Integer[] i = { 1337, 424242 };
// 僅在堆上生成了一個對象
int[] i = { 1337, 424242 };
小結
當我們處于 N.O.P.E. 分支的深處時,應該極力避免使用包裝類。這樣做的壞處是給GC帶來了很大的壓力。GC将會為清除包裝類生成的對象而忙得不可開交。
是以一個有效的優化方法是使用基本資料類型、定長數組,并用一系列分割變量來辨別對象在數組中所處的位置。
遵循LGPL協定的 trove4j 是一個Java集合類庫,它為我們提供了優于整形數組 int[] 更好的性能實作。
例外
下面的情況對這條規則例外:因為 boolean 和 byte 類型不足以讓JDK為其提供緩存方法。我們可以這樣寫:
Boolean a1 = true; // ... syntax sugar for:
Boolean a2 = Boolean.valueOf(true);
Byte b1 = (byte) 123; // ... syntax sugar for:
Byte b2 = Byte.valueOf((byte) 123);
其它整數基本類型也有類似情況,比如 char、short、int、long。
不要在調用構造方法時将這些整型基本類型自動裝箱或者調用 TheType.valueOf() 方法。
也不要在包裝類上調用構造方法,除非你想得到一個不在堆上建立的執行個體。
非堆存儲
當然了,如果你還想體驗下堆外函數庫的話,盡管這可能參雜着不少戰略決策,而并非最樂觀的本地方案。