2014-03-05 40 views
27

以下代碼段發出編譯時錯誤。Java中的最終字符

char c = 'c'; 
char d = c + 5; 

在第二行中的錯誤表示,

possible loss of precision 
    required: char 
    found: int 

該錯誤消息是基於NetBeans IDE中。


當這個角色c聲明final像如下。

final char c = 'c'; 
char d = c + 5; 

編譯器時錯誤消失。

這是無關的final strings

的情況下什麼是final修改在這裏做一個區別?

+2

編譯器是否足夠聰明,在第二種情況下,'c + 5'是恆定的? – vikingsteve

+1

好問題,答案必須在JLS的某個地方...讓我們等待,直到有人非常高興找到它。 – skiwi

+0

檢查[這個答案](http://stackoverflow.com/a/21187200/1686291) –

回答

24

的原因是,JLS #5.2 (Assignment conversion)這樣說:

如果表達式爲類型字節,短,炭或int的常量表達式(§15.28),一個基本收縮轉換可以,如果可以使用變量的類型是byte,short或char,常量表達式的值可以用變量的類型表示。

在你的榜樣,char c = 'c';不是a constantfinal char c = 'c';是。

基本原理可能是加法運算符+首先將其操作數轉換爲整數。所以這個操作可能會溢出,除非在這種情況下編譯器可以證明沒有溢出。

+0

即將發佈:) –

+1

我認爲這個人屬於Josh Bloch的* Jave Puzzlers * :) – einnocent

+1

我會補充一點,即使c不是最終的,如果使用+ =操作符(它有一個隱式轉換,但c = c + i;不要),所以c + = i與c =(char)(c + 1)相同;以防萬一你想將它作爲提示添加到答案 – Frakcool

15

When you apply the + operator to integral types

二元數值提升是對操作數執行(§5.6.2)。

在這種情況下,char值被提升爲int的值。

這裏

char c = 'c'; 
char d = c + 5; 

c因爲不是一個常量表達式,編譯器不能確定是否它是一個intc + 5值將能夠適合在一個char

在這種

final char c = 'c'; 
char d = c + 5; 

c哪裏是一個常量表達式,編譯器可以確定的c的值,這是99,加入5,這是104char倒是可以。 由於此保證,Java可以安全地執行從intchar的縮小轉換。

相反,如果你有

final char a = Character.MAX_VALUE;  
char b = (a + 5); 

,你會看到類似的行爲作爲你的第一個測試案例作爲a + 5值不適合在char。編譯器確定從a + 5產生的int值不適合char

+3

+1更好的解釋在恕我直言。 – Songo

+0

+1,因爲它明確指出,在編譯器的觀點中,「c」可能會在這些語句之間發生變化。 – TC1