我們真的理解 Java 裡的整型嗎
整型是我們日常生活中最常用到的基礎資料型別,看這篇文章之前,我想問:
我們真的像自己認為的那麼理解 Java 內的整型嗎?
也許看完本篇文章你就有自己的答案。
C 語言 提供瞭如下的整型
學習 Java 的整型之前,讓我們看看它的前輩——C 語言的實現。
讓我們更好地瞭解它的設計。
資料型別 | 佔用位元組 | 取值範圍 |
---|---|---|
signed char | 1 byte(8 bit) | -2^7, 2^7-1 |
signed short | 2 byte(16 bit) | -2^15, 2^15-1 |
signed int | 4 byte(32 bit) | -2^31, 2^31-1 |
signed long | 4 byte(32 bit) | -2^31, 2^31-1 |
signed long long | 8 byte(64 bit) | -2^63, 2^63-1 |
unsigned char | 1 byte(8 bit) | 0, 2^8-1 |
unsigned short | 2 byte(16 bit) | 0, 2^16-1 |
unsigned int | 4 byte(32 bit) | 0, 2^32-1 |
unsigned long | 4 byte(32 bit) | 0, 2^32-1 |
unsigned long long | 8 byte(64 bit) | 0, 2^64-1 |
Java 提供瞭如下整型
Java 則簡單了很多。
資料型別 | 佔用位元組 | 取值範圍 |
---|---|---|
byte | 1 byte(8 bit) | -2^7, 2^7-1 |
short | 2 byte(16 bit) | -2^15, 2^15-1 |
int | 4 byte(32 bit) | -2^31, 2^31-1 |
long | 8 byte(64 bit) | -2^63, 2^63-1 |
Java 和 C 整型的區別
-
C的整型大小與作業系統的位數直接相關, 需要通過 sizeof 運算子先算出預設位數。 Java統一了位數。
-
C的整型存在 unsigned 和 signed 的區別,而 Java 只有 signed。
優勢:更簡單,不會遇到 unsigned 和 signed 整型進行運算的隱式轉換問題。
劣勢:如果碰到 unsigned 的整型,會用儲存容量更大的來儲存。
例子
- unsigned byte 在 Java 中儲存為 short
- unsigned short 在 Java 中儲存為 int
- unsigned int 在 Java 中儲存為 long
- unsigned long 在 Java 中儲存為 BigDecimal
注: java 8 新增了 unsigned 相關的API,可以通過API計算。
或採用 Guava 的 unsigned整數實現。 例如(com.google.common.primitives.UnsignedInteger) -
C 語言存在的整型溢位問題, 而 java.lang.Math包 提供了 xxxExact() 方法。
java 的裝箱問題
原始資料型別 | 佔用位元組 | 包裝類 | 佔用位元組 |
---|---|---|---|
byte | 1 byte(8 bit) | Byte | 16 byte(128 bit) |
short | 2 byte(16 bit) | Short | 16 byte(128 bit) |
int | 4 byte(32 bit) | Integer | 16 byte(128 bit) |
long | 8 byte(64 bit) | Long | 16 byte(128 bit) |
包裝類的劣勢
- 在資料密集型操作中,記憶體消耗會對效能產生巨大影響
- 基礎型別存在預設值,而包裝類可能存在 null,引起空指標異常
- 基礎型別可以通過 == 判斷大小,包裝型別判斷大小需要用 equals() 方法
包裝類的優勢
- 包裝類會快取例項,減小記憶體消耗。
比如: Integer 會快取 -128, 127內的例項 - 支援新特性,比如泛型,lambda表示式。
- 包裝類提供了物件操作,封裝了一些實用的方法
比如:- Integer 繼承了 Number 類, 可以和其他的 Number 子類進行轉化
- Integer 實現了 Comparable 介面
- Integer 存在 unsigned API (java8)
- Integer 提供了轉化為二、八、十六進位制的 API
- Integer 提供了構造方法,並在其中校驗了入參是否合法
- Integer 提供了四則運算等算數API
Java 並不完美,它可以更好
從現在往回追溯,Java 的 Integer 事實上源於一個妥協。由於 java 號稱完全物件導向,而在最初的版本中卻存在 byte, short, int, long, char, boolean, float, double 這八種原始資料型別(primitive data types)。
在 Java 中我們無法寫出類似下面的程式碼
3.toString();
而在一些更加純粹的面嚮物件語言,則可以實現上述程式碼。
例如 Scala
3.toString();
引用
- Java Notes For Professionals.pdf
- Java 語言規範
感謝
希望對你有所幫助!