2012-02-20 61 views
9

有人可以解釋java字節類型嗎?Java字節類型很奇怪嗎?

這並不編譯:

byte b1 = 9; 
byte b2 = 1; 
byte b3 = b1 + b2; 

雖然這確實:

byte b4 = 9 + 1; 
byte b5 = (char)(9+1); 

此外,分配給長不起作用,即使該值適合一個字節:

byte b7 = (long)127; 

它會變得與包裝怪異

這將編譯:

Byte b6 = (int)3; 

但這並不:

Integer i = (byte)3; 
+1

沒有錯誤信息和投訴的行號,這是很難回答的。 – bmargulies 2012-02-20 18:26:22

+0

另外,'byte x = 126 + 1;'有效,但不能'byte y = 126 + 2;'不知何故,當使用可計算的值時,編譯器檢查容器是否足夠寬。雖然在JLS中找不到引用。 – gawi 2012-02-20 18:40:03

+0

這是在這個問題的答案中詳細討論:[鏈接](http://stackoverflow.com/questions/81392/java-why-do-i-receive-the-error-message-type-mismatch-cannot -convert-int-to-b) – 2012-02-20 18:49:05

回答

3

b6由於文字常量的編譯時縮小而工作。 B7不起作用,因爲編譯時縮小被限制在所有原始數據,但長期(有點怪,不知道爲什麼)

有趣的部分是§5.2 of the JLS

In addition, if the expression is a constant expression (§15.28) of type byte, short, char or int : 

A narrowing primitive conversion may be used if the type of the variable is byte, short, or char, and the value of the constant expression is representable in the type of the variable. 
A narrowing primitive conversion followed by a boxing conversion may be used if the type of the variable is : 

- Byte and the value of the constant expression is representable in the 
    type byte. 

- Short and the value of the constant expression is representable in 
    the type short.  

- Character and the value of the constant expression is representable in the type char. 

If the type of the expression cannot be converted to the type of the variable by a conversion permitted in an assignment context, then a compile-time error occurs. 

不知道爲什麼i沒有工作,雖然 - 擴大應該工作得很好,事實上,編譯器無論如何應該產生類似Integer.valueOf((byte)3);的東西。使用顯式調用按預期工作,即正在擴大。

有趣的是,使用eclipse Java編譯器Integer i = (byte) 3;編譯得很好,這讓我相信你剛剛在javac中發現了一個錯誤 - 恭喜! (或者是eclipse編譯器中的錯誤,但是eclipse的行爲對我來說似乎是正確的)。 FWIW我已經向oracle報告了針對javac的錯誤..

在JLS中找到正確的部分比格式化工作要少,因爲它有點可讀 - 如果您按照鏈接進行操作,可能會更容易。

+0

我也困惑了我......我猜它會被翻譯成類似= new Integer((byte)3));但是,這實際上會工作...... 我只是猜測它沒有真正澄清在JLS – 0x434D53 2012-02-21 04:23:25

+0

@ CSE不,編譯器使用'valueOf'方法(任何人都應該使用Wrapper API,構造函數實際上不應該公開) ,但是對我來說這似乎是一個錯誤,因爲顯式調用實際上起作用。 [這裏是](http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7147289)bugreport,儘管在撰寫時還沒有被oracle審查 - 可能需要幾天時間。 – Voo 2012-02-21 04:24:51

-1

第一個片段由於默認情況下所有數字常數產生編譯錯誤是int S IN的Java。

+2

但是,然後前兩行應該失敗? – 0x434D53 2012-02-20 18:30:23

+0

請注意解釋一個downvote,請。 – Roman 2012-02-20 18:30:56

+0

@CSE:這正是我在這個答案中描述的。 – Roman 2012-02-20 18:31:29

8

Java語言規範5.6.2二進制數字升級:「否則,兩個操作數都轉換爲int類型」。

因此,Java將兩個操作數轉換爲int,所以添加的結果是一個int。

此外:b3和b4之間的區別是,在b4中它是一個常量表達式(15.28),在b3中它是字面值。

+0

JVM規格,有你需要的。 http://java.sun.com/docs/books/jvms/second_edition/html/Concepts.doc.html#16021 – jn1kk 2012-02-20 18:48:06

+0

包裝類是怎麼回事?似乎直觀的是int可以適合一個字節,但一個字節不能適合整數 – 2012-02-20 19:05:55

+0

仍然試圖找出包裝。很難弄清楚規格會發生什麼。 – 0x434D53 2012-02-20 19:30:28