2017-04-13 67 views
7
short s = 'a';  // valid 
Short ss = 'a';  // valid 
int i = 'a';   // valid 
Integer ii = 'a'; // invalid 

爲什麼Integer ii ='a'無效,但是int i ='a'有效嗎?爲什麼短ss ='a'有效,但整數ii ='a'無效?java奇怪的分配規則


另一組問題:

byte b; 
final short s = 1; 
final Short ss = 1; 
final int i =1; 
final Integer ii = i; 
final long L = 1; 
final Long LL =1L; 

b = s;  // valid 
b = ss; // invalid 
b = i;  // valid 
b = ii; // invalid 
b = L;  // invalid 
b = LL; // invalid 

爲什麼B =升;無效,而b = s;有效?

請不要說這都是因爲JLS這麼說的。我想知道爲什麼JLS有這些不一致和不直觀的規則。我錯過了什麼?

+6

因爲自動裝箱(和原始擴展轉換)不能使'char'成爲Integer。嘗試'Integer ii =(int)'a'; ' –

+0

ii是類的實例,而我是整型數據類型的實例。 – Omore

+1

在java中學習'Autoboxing and Unboxing'的好時機。 https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html – yogidilip

回答

5

所以,該行:

Short s = 'a'; // is valid ... 

由於是無符號16位值(最大值爲65,536)和是帶符號的16位值(最大值爲32,767),所以有一個縮小的原始轉換(char to short),然後是一個裝箱轉換(short to short)。

short s = 'a'; // is valid - this is a narrowing primitive conversion (char -> short) 

這些special cases

此外,如果表達式是 型字節,或INT的常量表達式:

  • 縮小比例如果 變量的類型是字節,或,恆定 表達式的值在變量的類型表示的,可以使用略去轉換。

可以 可以使用甲基本收縮轉換接着裝箱轉換如果變量的類型是:

  • 字節和常量表達式的值在 類型可表示字節

  • 和常量表達式的值在 型表示的。

  • 字符和常量表達式的值表示的是在 類型

讓我們進入下一個例子:

Integer ii = 'a'; // is invalid - not a special case according to Oracle docs 
int i = 'a';  // is valid - widening primitive conversion (char -> int) is allowed 

而更多的情況從你的問題:

byte b; 
final long L = 1; 
b = L // error - incompatible types 

爲什麼行b = L是無效的?因爲它不是上面,我們可以鑄造過程中丟失的信息描述一個特殊情況,這就是爲什麼你必須明確地執行它:

b = (byte) L; // is valid - narrowing primitive conversion (long -> byte) 

而且,看看成一個非常有用的table

在JLS文檔中有關於所有這些規則的大量信息,您無需擔心所有這些規則。我能說什麼關於你的最後一個問題是,沒有一個隱含的窄轉換文字的任意整數將需要在未來的情況下,投:

// Cast is permitted, but not required - profit! 
byte b = (byte) 100; 
short s = (short) 100; 

感謝,我們可以將其更改爲:

byte b = 100; 
short s = 100; 
+0

感謝您的詳細回答。我理解你的解釋。這完全是因爲JLS這麼說的。但爲什麼JLS有這個奇怪的規則?規則不一致。例如;只有在表達式是byte,short,char或int類型的常量表達式時纔會發生縮小原語。但不長久?長期有什麼問題? –

+0

@VincentQuan縮小的原始轉換永遠不會對'long'有意義,因爲它是最大的原始整數類型。 – Hulk