原始型與原始型打包原始型別
主要差異
身分與身分價值:
原語:它們沒有身份;具有相同值的兩個基元始終相等。
打包:它們是物件並且有一個標識;兩個物件可以具有相同的值但不同的標識。
空值:
基元: 總是有一個預設值(例如,int 為 0)。
Packed: 可能為 null,如果處理不當可能會導致 NullPointerException 例外。
表現:
原語:在時間和空間上更有效率。
打包: 由於建立額外物件而引入開銷。
混合基元和包時的常見問題
有問題的例子:
ComparatornaturalOrder = (i, j) -> (i 問題: 比較 i == j 比較引用,而不是值。
不正確的行為:naturalOrder.compare(new Integer(42), new Integer(42)) 傳回 1 而不是 0。解決方案:
使用 Integer.
類別的 CompareTo 方法或實用程式方法ComparatornaturalOrder = Integer::compare; 或者,修正原先的比較器:
ComparatornaturalOrder = (iBoxed, jBoxed) -> { int i = iBoxed; int j = jBoxed; return (i 2.自動拆箱與 NullPointerException
當使用可以為 null 的打包類型時,如果物件為 null,自動拆箱可能會引發異常。有問題的例子:
Integer i = null; if (i == 42) { System.out.println("Inacreditável"); }問題: i 為空;與 42 比較時,發生 null 自動拆箱,導致 NullPointerException.
解決方案:盡可能使用原始型別。int i = 0; if (i == 42) { System.out.println("Inacreditável"); }3.由於自動裝箱/拆箱導致性能下降
在密集型操作中無意中使用包裝類型可能會由於自動裝箱和不必要的物件創建而導致效能下降。有問題的例子:
Long sum = 0L; for (long i = 0; i問題: sum 是一個壓縮的 Long;在每次迭代中,都會發生自動裝箱/拆箱。
影響:程式碼速度慢很多,記憶體使用量過多。
解決方案:
在密集操作中使用局部變數的原始類型。Long sum = 0L; for (long i = 0; i何時使用封裝類型
- 集合:在泛型集合中不能使用原始型別(例如列表)。
- 泛型參數:泛型類型不支援原始型別(例如ThreadLocal)。
- 需要物件的 API:某些 API 需要物件而不是原始類型。
良好實務
- 首選原始類型:只要有可能,就使用原始類型以實現簡單性和效率。
- 請小心自動裝箱/拆箱:自動裝箱可減少冗長,但可能會引入微妙的錯誤。
- 避免在 Wrapped 中與 == 進行比較:使用 equals() 等方法或比較展開的值。
- 檢查空值:使用封裝類型時,請注意它們可能為空並導致 NullPointerException。
概括
原始型別:
更簡單、更快。
它們不能為空。
他們沒有身分(只有價值)。打包型:
需要在集合和通用 API 中使用。
它們可以為空。
他們有對象標識。
免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。
Copyright© 2022 湘ICP备2022001581号-3