2016-04-11 15 views
5

Ho incontrato incomprensioni di promozione primitiva nel successivo frammento di codice.promozione primitiva per >> [Java]

byte a = 2; 
int b = a >> 4L; 

Cosa mi aspetto?

long b = (int)a >> 4L;
long b = a >> 4L;
int b = a >> 4L;

int >> long promuoverà la più grande tipo di dati (long) e non si compila con provocato int tipo.

Cosa ho ricevuto?

Compilano bene. Perché?

+1

Le regole di ampliamento non prendono in considerazione l'operazione binaria, solo l'operando più largo ad es. 'x% (byte) b' non può possibilmente essere più largo di un' byte' e tuttavia non è mai un 'byte' –

risposta

3

Il JLS non "promuoverà il tipo di dati più grande" qui, perché non esegue la promozione numerica binaria per gli operatori di spostamento. Questo è coperto dallo JLS, Section 15.19.

La promozione numerica unaria (§5.6.1) viene eseguita separatamente su ciascun operando. (Promozione numerico binario (§5.6.2) è non eseguita su operandi.)

promozione numerica unario promuove il byte a a un int. Il valore letterale 4L non è stato modificato, ma deve essere comunque un tipo integrale.

È un errore in fase di compilazione se il tipo di ciascuno degli operandi di un operatore di turno, dopo la promozione numerica unaria, non è un tipo integrale primitivo.

Quindi per lo spostamento vengono utilizzati solo 5 bit significativi per spostare uno int.

Se il tipo di promotore dell'operando di sinistra è int, solo i cinque bit di ordine inferiore dell'operando di destra vengono utilizzati come distanza di spostamento. È come se l'operando di destra fosse soggetto a un operatore AND logico bit a bit & (§15.22.1) con il valore di maschera 0x1f (0b11111). La distanza di spostamento effettivamente utilizzata è quindi sempre compresa tra 0 e 31.

Il risultato dell'operatore è un int, non un long, quindi possono essere assegnati ad un int senza un errore di compilazione.

Il tipo di espressione di spostamento è il tipo di promozione dell'operando di sinistra.

1

A JLS:

Il tipo dell'espressione spostamento è il tipo promosso dell'operando sinistro.

L'operando di destra di un operatore di turno non ha alcun effetto sul tipo di espressione. A differenza di un operatore come +, un tipo più grande a destra non significa che il risultato potrebbe essere più grande o più piccolo.