Embora seja tarde demais, gostaria de dar minha opinião sobre isso, pois pode esclarecer por que a solução fornecida por JB Nizet funciona. Eu me deparei com este pequeno problema trabalhando em um analisador de bytes e na conversão de strings. Quando você copia de um tipo integral de tamanho maior para um tipo integral de tamanho menor, pois este documento java diz que isso acontece:
https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.3
Uma conversão de estreitamento de um inteiro com sinal em um tipo integral T simplesmente descarta todos, exceto o n mais baixo bits de ordem, onde n é o número de bits usados para representar o tipo T. Além de uma possível perda de informação sobre a magnitude do valor numérico, isso pode fazer com que o sinal do valor resultante seja diferente do sinal do valor de entrada .
Você pode ter certeza de que um byte é um tipo integral, pois este documento java diz
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
byte: O tipo de dados de byte é um dois de 8 bits assinado complemento inteiro.
Portanto, no caso de converter um inteiro (32 bits) em um byte (8 bits), basta copiar o último (8 bits menos significativos) desse inteiro para a variável de byte fornecida.
int a = 128;
byte b = (byte)a; // Last 8 bits gets copied
System.out.println(b); // -128
A segunda parte da história envolve como os operadores unários e binários Java promovem operandos.
https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.2 A
conversão primitiva de ampliação (§5.1.2) é aplicada para converter um ou ambos os operandos, conforme especificado pelas seguintes regras:
Se um dos operandos for do tipo double, o outro será convertido em double.
Caso contrário, se um dos operandos for do tipo float, o outro será convertido para float.
Caso contrário, se um dos operandos for do tipo long, o outro será convertido em long.
Caso contrário, ambos os operandos são convertidos para o tipo int.
Fique tranquilo, se você estiver trabalhando com tipo integral int e / ou inferior, ele será promovido 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
Também arranhei minha cabeça em torno disso :). Há uma boa resposta para isso aqui por rgettman.
Operadores bit a bit em java apenas para inteiros e longos?