日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

靈魂拷問:為什么short、byte會被提升為int?boolean到底多大?

 

為什么short、byte會被提升為 int ?

在學習JAVA語法的時候,知道short 、byte、byte 類型在做運算符號的時候,都會默認提升為 int,例如下面的代碼就是無法通過編譯的,需要將等于號右邊的強制轉為 short 才可以。

public static void main(String[] args) {    short a = 1;    short b = 2;    a = a + b;           // 編譯不過    short c = a + b;  // 編譯不過}

為什么兩個 short 相加會變成 int,有的人解釋說,兩個 short 相加可能溢出,所以用 int 來接就不會溢出,那這樣的話,兩個 int 相加豈不應該是 long 類型嗎?其實本質的原因要從字節碼開始講起。

Java虛擬機的指令由一個字節長度的、代表著某種特定操作含義的數字(稱為操作碼,Opcode)以及跟隨其后的零至多個代表次操作所需參數(稱為操作數,Operands)而構成。

Java虛擬機的指令集中的大多數都對它們執行的操作的數據類型進行編碼,例如 iload 指令,是將一個局部變量加載到操作棧,且這個局部變量必須是 int 類型。

由于操作碼的長度為一個字節,這意味著指令集的操作碼總數不可能超過256條,這也為設計包含數據類型的操作碼帶來了很大壓力:如果每一種與數據類型相關的指令都支持Java虛擬機所有運行時數據類型的話,那指令的數量就會超出一個字節所能表示的數量范圍了。

根據下表(出自 Table 2.11.1-A. Type support in the Java Virtual machine instruction set),可以發現大部分指令都沒有支持 byte、char 和 short 類型,甚至沒有任何指令支持 boolean 類型。編譯器會在編譯器或運行期將 byte 和 short 類型帶符號擴展為 int 類型, boolean 和 char 類型零位擴展為相應的 int 類型。與之類似,在處理 boolean、byte、char 和 short 類型的數組時,也會轉為使用相應的 int 類型的字節碼來處理指令。 因此,大多數對于 boolean、byte、char 和 short 類型數據的操作,實際都是使用 int 類型作為運算類型。另外還有第二點原因,在設計虛擬機時,主要考慮的是 32位體系,32位系統使用 4 字節是最節省,因為 CPU 只能 32位32位的尋址。

如果想詳細查看各個指令,可以參考Java虛擬機規范

靈魂拷問:為什么short、byte會被提升為int?boolean到底多大?

 

Java 中 boolean 到底多大?

我們繼續深入思考, boolen 到底有多大? 在學 Java 的時候, 都說 byte、boolen 類型占 1字節,但上面又提到, byte 會被提升為 int 類型,那么就應該占了 4字節。沒錯,虛擬機規范只有 4字節 和 8字節類型(long、float), boolean、char、short 都是占了 4字節。

我們來看一例子。

public class Test {    byte aByte = 2;    short aShort = 3;        public void byteAdd() {        aByte = (byte) (aByte + 1);    }    public void shortAdd() {        aShort = (short) (aShort + 1);    }}

先編譯此文件javac Test.java,查看 Class 內容,javap -verbose Test,摘取關鍵信息:

{  byte aByte;    descriptor: B    flags:  short aShort;    descriptor: S    flags:  public void byteAdd();    descriptor: ()V    flags: ACC_PUBLIC    Code:      stack=3, locals=1, args_size=1         0: aload_0         1: aload_0         2: getfield      #2                  // Field aByte:B         5: iconst_1         6: iadd         7: i2b         8: putfield      #2                  // Field aByte:B        11: return  public void shortAdd();    descriptor: ()V    flags: ACC_PUBLIC    Code:      stack=3, locals=1, args_size=1         0: aload_0         1: aload_0         2: getfield      #3                  // Field aShort:S         5: iconst_1         6: iadd         7: i2s         8: putfield      #3                  // Field aShort:S        11: return}

觀察這兩個方法,第一第二行目的是將對應的變量壓入棧,第五行都是 iconst_1,將 int 類型的 1 壓入棧中,然后使用 iadd 方法,將兩個值相加,之后一個調用 i2b,一個調用 i2s 指令。我們隨便查看一個i2s的命令介紹 jvms-6.5.i2s,它是這樣描述的

The value on the top of the operand stack must be of type int. It is popped from the operand stack, truncated to a short, then sign-extended to an int result. That result is pushed onto the operand stack.

翻譯過來大致是:

操作數堆棧頂部的值必須是int類型。它從操作數堆棧中彈出,截斷為short,然后符號擴展為int結果。結果被推送到操作數堆棧上。

因此,可以看出 short、char 實際上也是占用了 和 int 一樣大的字節的。那我們平時所說 short 是 2 字節的豈不是錯誤的?并不是,對于單個 byte、char、short 類型的數據,在內存中實際會占 4 字節,但這對于數組來說并不適用, byte 數組每個元素占 1 字節, char、short 數組都占 2 字節。

參考stackoverflow中的回答 Size of a byte in memory - Java,注意標注高亮的部分。

更多對基本類型的描述,可以查看Primitive Data Types

說完byte、char、short,我們再來看看對于 boolean 的描述,摘取部分信息 2.3.4. The boolean Type:

Although the Java Virtual Machine defines a boolean type, it only provides very limited support for it. There are no Java Virtual Machine instructions solely dedicated to operations on boolean values. Instead, expressions in the Java programming language that operate on boolean values are compiled to use values of the Java Virtual Machine int data type.

 

The Java Virtual Machine does directly support boolean arrays. Its newarray instruction (§newarray) enables creation of boolean arrays. Arrays of type boolean are accessed and modified using the byte array instructions baload and bastore (§baload, §bastore).

 

In Oracle’s Java Virtual Machine implementation, boolean arrays in the Java programming language are encoded as Java Virtual Machine byte arrays, using 8 bits per boolean element.

翻譯大概如下:

盡管Java虛擬機定義了一種 boolean 類型,但對它的提供支持非常有限,沒有專門的虛擬機指令用來操作 boolean 類型。但是,對于有 boolean 值參與運行的表達式,都會被編譯成 int 類型的數據。

 

虛擬機直接支持了 boolean 數組,它使用newarray指令來創建數組,并可以使用 baload 和 bastore 來訪問和修改 boolean 類型的數組

 

在 Oracle 的Java虛擬機實現中, boolean 類型的數組被編碼成和 byte類型的數組, 每個 boolean 元素使用 8 bit。

所以虛擬機規范是這樣定義的:boolean 單獨使用時,占 4 字節,在數組中使用時,占 1 字節。但最終如何實現,還是要看各個虛擬機廠商是否遵守規范了。

分享到:
標簽:boolean
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定