Java隨談(六)## 我們真的理解 Java 裡的整型嗎?

2022-06-07 18:01:32

我們真的理解 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 整型的區別

  1. C的整型大小與作業系統的位數直接相關, 需要通過 sizeof 運運算元先算出預設位數。 Java統一了位數。

  2. 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)

  3. 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)

包裝類的劣勢

  1. 在資料密集型操作中,記憶體消耗會對效能產生巨大影響
  2. 基礎型別存在預設值,而包裝類可能存在 null,引起空指標異常
  3. 基礎型別可以通過 == 判斷大小,包裝型別判斷大小需要用 equals() 方法

包裝類的優勢

  1. 包裝類會快取範例,減小記憶體消耗。
    比如: Integer 會快取 -128, 127內的範例
  2. 支援新特性,比如泛型,lambda表示式。
  3. 包裝類提供了物件操作,封裝了一些實用的方法
    比如:
    • 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();

參照

  1. Java Notes For Professionals.pdf
  2. Java 語言規範

感謝

希望對你有所幫助!