我在Eclipse中寫了下面的代碼:java中的位運算符只用於整數和長整型?
byte b = 10;
/* some other operations */
b = ~b;
的Eclipse想強制轉換爲字節按比特補線。它說:「類型不匹配:不能從int轉換爲字節」。我也嘗試過使用其他按位運算和其他整型。它是短而且相同。只有long和integer才能使用按位操作。
是否有什麼原因呢?
我在Eclipse中寫了下面的代碼:java中的位運算符只用於整數和長整型?
byte b = 10;
/* some other operations */
b = ~b;
的Eclipse想強制轉換爲字節按比特補線。它說:「類型不匹配:不能從int轉換爲字節」。我也嘗試過使用其他按位運算和其他整型。它是短而且相同。只有long和integer才能使用按位操作。
是否有什麼原因呢?
一元(如~
)和二元運算它們的操作數,以"unary numeric promotion" (JLS, Section 5.6.1)和"binary numeric promotion" (JLS, Section 5.6.2)分別花式的條款「促進事情至少int
第一」。
具體而言,一元數值升級,引述JLS部上面鏈接:
一些運營商採用一元數值升級到一個單個操作數,其必須產生一個數字式的值:
和
...如果操作數是編譯時類型字節,短,或炭的,它是由一個加寬原語轉換被提升爲int類型的值(§ 5.1.2)。
(二元數值提升是相似的,在兩個操作數操作。)
所以,即使b
是byte
,~b
是int
,因爲b
的價值被提升了一個int
。
解決辦法:將它轉換回一個byte
:
b = (byte) (~b);
爲什麼,Java的?
這留下了問題,爲什麼?對於我能找到的操作員來說,用於在byte
s,short
s和char
上操作的JVM字節碼指令根本不存在。例如,您正在使用的一元位運算符(〜)is implemented as an "XOR" operation with -1
(all bits set)。從該鏈接:
tempSpock &= ~mask;
成爲
25 iload_2 // Push local variable 2 (mask).
26 iconst_m1 // Push -1.
27 ixor // Bitwise EXCLUSIVE-OR top two ints: ~mask
但是,我只能find instructions for XOR(以及其它一元和二元運算太)爲int
S和long
S(float
和double
版本存在其他運營商在適當情況下)。
因此,Java必須執行這些促銷活動,因爲在byte
s,short
s或char
s上沒有用於執行這些操作的字節碼指令。
爲什麼不呢,JVM?
這引出了另一個問題:爲什麼JVM不支持這種字節碼指令?答案似乎是,「因爲在單字節指令集中編碼它們會太多。」按照JVM Specification, Section 2.11.1,
鑑於Java虛擬機的一個字節的操作碼大小,編碼類型到其指令集的設計操作碼的地方壓力。如果每種類型的指令都支持所有的Java虛擬機的運行時數據類型,則將會有比指令更多的指令。相反,Java虛擬機的指令集爲某些操作提供了降低的類型支持級別。換句話說,指令集有意不是正交的。根據需要,可以使用單獨的指令在不支持和受支持的數據類型之間進行轉換。
(重點煤礦)
總之,JVM的一個字節碼指令集排除在byte
S,char
s和short
S代表大多數操作的字節碼指令,因此需要一元數值升級和二進制數值提升。
你的字節碼參數是無稽之談。如果這是由語言指定的,編譯器可以很好地添加強制轉換。舉一個例子,看看'short'是如何定義'+ ='的。 – starblue
是的,小於int
的類型經過升級用作大多數運算符的操作數。首先將它們有效地轉換爲int
。因此,在上面的代碼中,結果的類型是int
。有關詳細信息,請參閱JLS的this section。
至於爲什麼 Java這樣做,我不確定。但有一個可能的原因是C做到了這一點,並且保持熟悉的語義可能是語言設計目標。在Java中受試者
也許是因爲計算機必須對至少32位長的整個寄存器執行操作? – user2573153
是啊!這可能是原因。 –