Java中兩個byte型別相加結果賦值給byte型別的變數會報編譯錯誤,byte加byte的結果為什麼是int?
背景:
之前偶然看到有討論這個問題,在網上搜了半天,結果都不盡如人意,解釋沒有到位,
有的說byte加byte預設就是int,那為什麼這麼做呢? 這不是找麻煩麼?這種奇怪的預設還有哪些?帶來一些列疑問。。。。。。
有的說byte儲存的就是整型資料,這種說法的對錯姑且不論,至少我覺得難免有點牽強了,還是疑問重重。。
所以今天專門總結一下:
----------------------------------------------------------------------------------------------------------------------------------------------------------------
一、問題:
先看這段程式碼:
(1) byte a=1;
(2) byte b=2;
(3) byte d=-1;
(4) byte c=128; //編譯錯誤,因為byte型別的資料是單位元組,表示十進位制數的範圍是-128~+127(第一位是符號位,代表正負數)
(5) a = a+b;//編譯錯誤,byte+byte的結果不是byte型別,提示需要強制轉換為byte型別或者把等式左邊型別改編為int.
(6) a = (byte)(a+b);
(1)(2)(3)行,正常賦值操作,沒有問題;
(4)行,編譯錯誤,實際上是因為byte型別的資料是單位元組,表示十進位制數的範圍是-128~+127;
(5)行,就是今天的重點了,也報了編譯錯誤,byte+byte的結果不是byte型別,反而提示需要強制轉換為byte型別或者把等式左邊型別改編為int. 就如第(6)行那樣。 這就像兩個人站在一起,需要有人強制解釋一下,別人才知道這是兩個人,而不是其他的什麼東西,這也太奇怪了!
二、對背後原因的探索:
要了解清楚這個問題的原因,必須要從Java虛擬機器的指令集說起,每種指令代表了一種操作。
首先要說明的是:在Java虛擬機器中,對於大部分與資料型別相關的位元組碼指令,他們的操作碼助記符中都有特殊的字元來表示專門為哪種資料型別服務。
但是Java虛擬機器的操作碼長度只有一個位元組,這就帶來一個問題,如果每種與資料型別相關的指令都支援Java虛擬機器執行時資料型別的話,顯然一個位元組就不夠用了。 所以Java虛擬機器規範中,這種特性"Not Orthogonal",並非每種資料型別和每一種操作都有對應的指令。
大部分的指令都沒有支援byte、char、short,沒有任何指令支援boolean型別。編譯器在編譯期或者執行期將byte和short型別的資料帶符號擴充套件為相應的int型別資料,將boolean和char型別資料零位擴充套件為相應的int型別資料。與之類似的,在處理byte、char、short和boolean型別的陣列時,也會轉換成對應的int型別的位元組碼指令來處理。因此,大多數對於byte、char、short和boolean型別資料的操作,實際上都是使用相應的int型別作為運算型別的。
參考書籍:《深入理解Java虛擬機器:JVM高階特性與最佳實踐》(第三部分,第6章,6.4.1小節:P197-P199 關於Java虛擬機器指令集所支援的資料型別相關的內容)