很早的時候由於工作需要,接觸過一點 Java,於是有了這個坑,今天回頭看到自己在 Stackoverflow 上提的問題發現了它,於是再記錄下。
在使用中,需要將 byte 類型的的每一位都置 1。我萬萬沒有想到這么一個簡單的操作,在 Java 中有各種約束。
首先看看代碼:
// 方式 1 byte allBitsOne = 0xFF;
// 方式2 byte allBitsOne = (byte)0xFF;
// 方式3 byte allBitsOne = 0xFFFFFFFF;
上面的哪個方式可以達到將 byte 類型的每一位都置 1 的需求呢?答案就是 2,3。
為什么方式 1 不可以呢?
因為在 Java 中,整型字面量(literal integers)是采用的固定的有符號 32 位整型來表示的。而 byte 類型在 Java 中又是一個有符號的 8 位類型,表示范圍是十進制 -128~127。於是 0xFF 代表的十進制 255 超過了 byte 類型的表示的范圍。
為什么方式 2 可以呢?
因為 0xFF 這個 32 位整型來說,低 8 位都是 1,現在用 (byte) 強制轉換一下,將其多余的高位都丟棄,於是剩下的 8 位都是 1 的 byte 賦值給左邊。
為什么方式 3 可以呢?
因為在 Java 中,整型字面量(literal integers)是采用的固定的有符號 32 位整型來表示的。並且是采用的補碼的形式,那么對於 0xFFFFFFFF 它所表示的數的絕對值就是各位按位取反后 + 1,可以知道絕對值是 1,而最高位是符號位,於是表示的就是 -1,再根據 byte 類型在 Java 中可以表示 -128~127,所以可以賦值,而 -1 在 byte 類型上就是每一位都是 1。
我覺得坑有兩個:
- 為什么 byte 類型在 Java 中要被設計成
Int8而不是UInt8? - Java 的類型系統太不靈活了,看看人家 Swift 中的 literal
