Anche se è troppo tardi, vorrei dare il mio contributo in merito in quanto potrebbe chiarire perché la soluzione fornita da JB Nizet funziona. Mi sono imbattuto in questo piccolo problema lavorando su un parser di byte e sulla conversione di stringhe da solo. Quando si copia da un tipo integrale di dimensioni maggiori a un tipo integrale di dimensioni inferiori, poiché questo documento java dice che questo accade:
https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.3
Una conversione restrittiva di un intero con segno in un tipo integrale T scarta semplicemente tutto tranne il n più basso bit dell'ordine, dove n è il numero di bit utilizzati per rappresentare il tipo T. Oltre a una possibile perdita di informazioni sull'ampiezza del valore numerico, ciò può far sì che il segno del valore risultante differisca dal segno del valore di input .
Puoi essere sicuro che un byte è un tipo integrale poiché questo documento java dice
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
byte: il tipo di dati byte è un due con segno a 8 bit complemento intero.
Quindi, nel caso di cast di un intero (32 bit) in un byte (8 bit), copi semplicemente l'ultimo (8 bit meno significativi) di quell'intero nella variabile byte specificata.
int a = 128;
byte b = (byte)a; // Last 8 bits gets copied
System.out.println(b); // -128
La seconda parte della storia riguarda il modo in cui gli operatori unari e binari Java promuovono gli operandi.
https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.2 La
conversione primitiva di ampliamento (§5.1.2) viene applicata per convertire uno o entrambi gli operandi come specificato secondo le seguenti regole:
Se uno degli operandi è di tipo double, l'altro viene convertito in double.
Altrimenti, se uno degli operandi è di tipo float, l'altro viene convertito in float.
Altrimenti, se uno degli operandi è di tipo long, l'altro viene convertito in long.
Altrimenti, entrambi gli operandi vengono convertiti nel tipo int.
Stai tranquillo, se stai lavorando con il tipo integrale int e / o inferiore verrà promosso a int.
// byte b(0x80) gets promoted to int (0xFF80) by the & operator and then
// 0xFF80 & 0xFF (0xFF translates to 0x00FF) bitwise operation yields
// 0x0080
a = b & 0xFF;
System.out.println(a); // 128
Mi sono grattato la testa anche su questo :). C'è una buona risposta per questo qui da rgettman.
Operatori bit per bit in java solo per interi e lunghi?