2010-09-09 85 views
16

有人可以向我解釋爲什麼下面的代碼在Java中編譯好嗎?用char和整數字面值在Java中的整數算術

char c = 'a' + 10; 

爲什麼這不等於下面的,它不會編譯?

int i = 10; 
char c = 'a' + i; 

Java語言規範(第3.10.1節)指出「字面一個整數是long類型的,如果它是與ASCII字母L或l(ELL)後綴;否則,它是int類型(§4.2的0.1)。」第4.2.2節提到「數字運算符,其結果爲intlong類型的值。」所以根據我的理解,添加的結果應該是int,它不能被分配給char變量c

但是,它編譯得很好(至少在Sun JDK 1.6.0 release 17和Eclipse Helios中)。

也許是一個人爲的例子,但它被用在我一直在教的Java入門課程中,現在我發現我不明白它爲什麼起作用。

+3

感謝所有回答。對於任何感興趣的人來說,語言規範(賦值轉換)的第5.2節實際上都會說「另外,如果表達式是byte類型的short表達式(第15.28節),則爲short,char或int:...縮小原語轉換如果變量的類型是byte,short或char,並且常量表達式的值可以用變量的類型表示,則可以使用它。「 – Ben 2010-09-10 09:09:40

+1

如果你像我一樣碰巧遇到了這個問題,因爲你想知道如何將索引字符轉換爲字符串,在這裏你可以去;當'i = 2'時,String.valueOf((char)('a'+ i))'返回字符串「c」。 – JohnnyLambada 2013-10-23 23:01:11

回答

9

'a' + 10編譯時間常量表達式'k'的值,它可以初始化char類型的變量。這與在[-128,127]中能夠使用文字整數指定byte變量相同。在[128,255]範圍內的byte可能更令人討厭。

+0

謝謝。查找*編譯時常量表達式*將我引向語言規範的相關部分。 – Ben 2010-09-10 09:12:59

13

這是因爲編譯器可以檢查它('a' + 10)是否在char的範圍內,而不能(通常)檢查'a' + <an integer>是否在範圍內。

+0

char c = 65535;編譯,但不是char c = 65536; – einarmagnus 2010-09-09 21:21:41

+0

字符是兩個字節,所以這是有道理的。 – einarmagnus 2010-09-09 21:23:52

+0

'char c = 103000;'不。 UCS-2 ftw! – 2010-09-09 21:24:43

1

該常數是一個不同的類型(我知道規範說10應該是一個int,但編譯器不會這樣看)。

char c = 'a' + 10,10實際上被認爲是一個char類型的常量變量(所以它可以被添加到a中)。因此char c = char + char的作品。

int i = 10; char c = 'a' + i;要添加炭爲整數(一個整數可以比一個char大得多,所以它選擇更大的數據類型[int]是結果a.k.a:'a' + i = int + int)。所以加法的結果是一個整數,它不適合char c

如果你明確鑄造i是一個字符(例如:char c = 'a' + (char)i;)它可以工作,或者如果你做了相反的(例如:int c = (int)'a' + i;),它會工作。

+0

我認爲說10被認爲是char類型是不正確的。相反,正如Tom Hawtin所說的,表達式'a'+ 10'是*編譯時常量*,因此編譯器可以進行縮小轉換。實際上,'char c ='a'+(char)i;'不起作用,因爲右側是int類型,不是編譯時常量。 – Ben 2010-09-10 09:17:02

3

char實際上是一個範圍爲0-65535的無符號16位整數。因此,您可以將該範圍內的任何整數字面量賦值給一個字符,例如「char c = 96」,從而導致「c」保持字符「a」。您可以使用System.out.println(c)打印結果。

對於「char c ='a'+ 10」右側的常量表達式,由於Java數字提升規則而將a提升爲int,整數值爲96.之後加10後,我們得到一個文字整數106,它可以被分配給一個字符。「char c ='a'+ i」的右側不是常量表達式,表達式結果分配規則需要從int到char的顯式轉換,即「char c =(char) ('a'+ i)「。