Незважаючи на те, що вже пізно, я хотів би дати свій внесок щодо цього, оскільки це може пояснити, чому працює рішення, надане JB Nizet. Я натрапив на цю маленьку проблему, працюючи над байтовим синтаксичним аналізатором та перетворюючи рядки сам. Коли ви копіюєте з інтегрального типу більшого розміру, на інтегральний тип меншого розміру, як сказано в цьому документі Java, це трапляється:
https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.3
Перетворення звуження підписаного цілого числа на інтегральний тип T просто відкидає всі, крім найнижчого порядок бітів, де n - кількість бітів, що використовується для представлення типу T. На додаток до можливої втрати інформації про величину числового значення, це може призвести до того, що знак результуючого значення буде відрізнятися від знака вхідного значення .
Ви можете бути впевнені, що байт є інтегральним типом, оскільки в цьому Java-документі написано
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
байт: Тип даних байта - це 8-розрядні двозначні знаки ціле число доповнення.
Отже, у випадку приведення цілого числа (32 біта) до байта (8 бітів), ви просто копіюєте останні (найменш значущі 8 бітів) цього цілого числа до заданої змінної байта.
int a = 128;
byte b = (byte)a; // Last 8 bits gets copied
System.out.println(b); // -128
Друга частина історії стосується того, як одинарні та двійкові оператори Java просувають операнди.
https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.2
Розширення примітивного перетворення (§5.1.2) застосовується для перетворення одного або обох операндів, як зазначено за наступними правилами:
Якщо будь-який операнд має тип double, інший перетворюється на double.
В іншому випадку, якщо будь-який операнд має тип float, інший перетворюється на float.
В іншому випадку, якщо будь-який операнд має тип long, інший перетворюється на long.
В іншому випадку обидва операнди перетворюються на тип int.
Будьте впевнені, якщо ви працюєте з інтегральним типом int та / або нижче, він буде підвищений до 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
Я теж почухав голову навколо цього :). Для цього тут є хороша відповідь від rgettman.
Побітові оператори в Java лише для цілих чи довгих?