2010-09-09 14 views
16

Qualcuno può spiegarmi perché il seguente codice viene compilato correttamente in Java?Aritmetica di interi in Java con char e intero letterale

char c = 'a' + 10; 

Perché questo non è equivalente al seguente, che non viene compilato?

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

Java Language Specification (sezione 3.10.1) indica "Un numero intero letterale è di tipo long se suffisso una lettera ASCII L o L (elle), altrimenti è di tipo int (§4.2 .1)." La sezione 4.2.2 fa riferimento a "Gli operatori numerici, che risultano in un valore di tipo int o long". Quindi il risultato dell'aggiunta dovrebbe, a mio avviso, essere un int, che non può essere assegnato alla variabile charc.

Tuttavia, compila bene (almeno in SunJDK 1.6.0 versione 17 e in Eclipse Helios).

Piuttosto un esempio artificiale, forse, ma è utilizzato in un corso introduttivo di Java che ho insegnato, e ora mi viene in mente che non capisco veramente perché funzioni.

+3

Grazie a tutti quelli che hanno risposto. Per chiunque sia interessato, la sezione 5.2 della specifica della lingua (Conversione di assegnazione) in realtà dice "Inoltre, se l'espressione è un'espressione costante (§15.28) di tipo byte, short, char o int: ... Una restringente conversione primitiva può essere usato se il tipo della variabile è byte, short o char e il valore dell'espressione costante è rappresentabile nel tipo della variabile. " – Ben

+1

Se tu, come me, capita di inciampare su questo perché vuoi sapere come effettivamente convertire un char indicizzato in una stringa, ecco qua; quando 'i = 2' quindi' String.valueOf ((char) ('a' + i)) 'restituisce la stringa" c ". – JohnnyLambada

risposta

9

'a' + 10 è un fase di compilazione espressione costante con il valore di 'k', che può inizializzare una variabile di tipo char. È lo stesso che poter assegnare una variabile byte con un numero intero letterale in [-128, 127]. Un byte nell'intervallo [128, 255] potrebbe essere più fastidioso.

+0

Grazie. Cercare l'espressione costante * in fase di compilazione * mi ha portato alla sezione pertinente delle specifiche del linguaggio. – Ben

13

È perché il compilatore può verificare che esso ('a' + 10) sia all'interno dei limiti di un carattere mentre non è in grado (in generale) di verificare che 'a' + <an integer> rientri nei limiti.

+0

char c = 65535; compila, ma non char c = 65536; – einarmagnus

+0

char è di due byte, quindi ha senso. – einarmagnus

+0

'char c = 103000;' no. Ftw UCS-2! –

1

La costante è di un tipo diverso (so che la specifica dice che 10 dovrebbe essere un int, ma il compilatore non la vede in questo modo).

In char c = 'a' + 10, 10 è effettivamente considerato una variabile costante di tipo char (quindi può essere aggiunto a). Pertanto, char c = char + char funziona.

In int i = 10; char c = 'a' + i; si aggiunge un char a un numero intero (un numero intero può essere molto più grande di un carattere, quindi sceglie il tipo di dati più grande [int] per essere il risultato a.k.a: 'a' + i = int + int). Quindi il risultato dell'aggiunta è un numero intero che non può essere inserito nello char c.

Se pressofuso esplicitamente i di essere un char (ad es .: char c = 'a' + (char)i;) potrebbe funzionare o se avete fatto il contrario (ad es .: int c = (int)'a' + i;) che avrebbe funzionato.

+0

Non penso sia corretto affermare che 10 è considerato di tipo char. Piuttosto, come dice Tom Hawtin, l'espressione ''a' + 10' è una costante * in fase di compilazione * e quindi il compilatore può eseguire una conversione restringente. In realtà 'char c = 'a' + (char) i;' non funziona perché il lato destro è di tipo 'int' e non è una costante in fase di compilazione. – Ben

3

char è in realtà un numero intero a 16 bit senza segno con un intervallo 0-65535. Pertanto, puoi assegnare qualsiasi valore letterale intero nell'intervallo a un carattere, ad esempio "char c = 96", che risulta in "c" contenente il carattere "a". È possibile stampare il risultato utilizzando System.out.println (c).

Per l'espressione costante sul lato destro di "char c = 'a' + 10", 'a' viene promosso a int first a causa delle regole di promozione numerica Java e il valore intero è 96. Dopo aggiungendo 10 ad esso, otteniamo un intero letterale 106, che può essere assegnato a un carattere.

Il lato destro di "char c = 'a' + i" non è un'espressione costante e la regola di assegnazione dei risultati dell'espressione richiede un cast esplicito da int a char, ovvero "char c = (char) ('a' + i) ".

Problemi correlati