2015-05-20 15 views
24

Ho testato il casting char e mi ha attraversato questo:Java char a byte colata

public class Test { 
    public static void main(String a[]) { 
     final byte b1 = 1; 
     byte b2 = 1; 
     char c = 2; 

     c = b1; // 1- Working fine 
     c = b2; // 2 -Compilation error 
    } 
} 

Qualcuno può spiegare il motivo per cui sta funzionando benissimo in 1 quando ho aggiunto una finale al byte?

+0

In generale, la trasmissione da byte a caratteri e viceversa non è una buona pratica poiché questo ignora la codifica. – Necreaux

risposta

18

Quando la variabile è final, il compilatore Inlines automaticamente il suo valore che è 1. Questo valore è rappresentabile come char, cioè:

c = b1; 

è equivalente a

c = 1; 

Infatti, secondo this section on final variables, b1 viene considerato come una costante:

Una variabile di tipo primitivo o tipo String, ovvero final e inizializzata con un'espressione costante in fase di compilazione (§15.28), è denominata variabile costante .

+2

non dovrebbe fare alcuna differenza – loonytune

+3

@loonytune Sì, il compilatore lo fa. Verificato usando 'javac 1.7.0_75'. – manouti

+1

Sei corretto, verificato anche su java 8. Sono davvero sorpreso, probabilmente ha a che fare con qualcosa come essere una voce costante nella tabella dei simboli durante la compilazione e non essere affatto una variabile. Ci scusiamo per questo, ha messo in su il tuo commento e ha risposto ... – loonytune

0

Beh, la sua causa di byte è un tipo firmato mentre char non è, quindi u bisogno di applicare conversione di tipo esplicita per (2)

c = (char)b2; 

anche la dichiarazione finale ha lavorato per 1 perché prima della compilazione , il compilatore è in grado di confermare che non vi è alcuna perdita dovuta alla conversione poiché '1' è nell'intervallo di char, prova a mettere '-1' con la stessa istruzione finale in (1) otterrai nuovamente un errore di compilazione.

Tutto ciò si riduce alla compatibilità del tipo tra tipi firmati e non firmati, che devono essere esplicitamente eseguiti in java.

10

La conversione da byte a char è una conversione primitiva di allargamento e restringimento, come descritto in paragraph 5.1.4 della specifica del linguaggio Java.

Come descritto da JLS, ciò avviene tramite una fase intermedia; il byte viene convertito in int tramite una conversione primitiva allargata e quindi lo int viene convertito in char tramite una conversione primitiva restrittiva (vedere 5.1.3).

Paragraph 5.2 spiega quando un cast è necessaria quando si esegue un incarico:

... se l'espressione è una costante espressione (§15.28) di tipo byte, short, char, o int:

  • Una conversione primitiva restrittiva può essere utilizzata se il tipo della variabile è byte, short, oppure char e il valore dell'espressione costante è rappresentabile nel tipo della variabile.

La variabile b1 è davvero una costante, ma la variabile b2 non è, quindi questa regola vale per b1 ma non per b2.

Quindi: è possibile assegnare b1-c perché b1 è una costante e il valore della costante, 1, si inserisce in un char, ma non è possibile assegnare ad b2c senza un cast perché b2 non è una costante.

+0

Quindi ... molto ... complessità ... –

+0

@PaulDraper Bene, queste sono solo le regole ufficiali delle specifiche del linguaggio, che spiegano esattamente perché uno funziona e l'altro è un errore. Alla fine tutto ciò che devi ricordare è che non è necessario eseguire il cast se è una costante. Il motivo per cui non è necessario eseguire il cast in questo caso è per comodità. – Jesper