Здесь есть хорошие ответы, но я не вижу демонстрации побитовых операций. Как говорит Visser (в настоящее время принятый ответ), Java по умолчанию подписывает целые числа (Java 8 имеет целые числа без знака, но я никогда не использовал их). Без дальнейших церемоний, давайте сделаем это ...
Пример RFC 868
Что произойдет, если вам нужно записать целое число без знака в IO? Практический пример - когда вы хотите вывести время в соответствии с RFC 868 . Для этого требуется 32-разрядное целое число без знака с прямым порядком байтов, которое кодирует количество секунд с 12:00 утра 1 января 1900 года. Как бы вы это закодировали?
Создайте свое собственное 32-разрядное целое число без знака, например:
Объявить байтовый массив из 4 байтов (32 бита)
Byte my32BitUnsignedInteger[] = new Byte[4] // represents the time (s)
Это инициализирует массив, см. Являются ли байтовые массивы инициализированными в ноль в Java? , Теперь вам нужно заполнить каждый байт в массиве информацией в порядке с прямым порядком байтов (или с прямым порядком байтов, если вы хотите разрушить хаос). Предполагая, что у вас есть long, содержащий время (длинные целые числа имеют длину 64 бита в Java), который называется secondsSince1900
(который использует только первые 32 бита, и вы обработали тот факт, что Date ссылается на 12:00 AM 1 января 1970 г.), затем вы можете использовать логическое «И» для извлечения битов из него и смещения этих битов в позиции (цифры), которые не будут игнорироваться при приведении к байту и в порядке с прямым порядком байтов.
my32BitUnsignedInteger[0] = (byte) ((secondsSince1900 & 0x00000000FF000000L) >> 24); // first byte of array contains highest significant bits, then shift these extracted FF bits to first two positions in preparation for coersion to Byte (which only adopts the first 8 bits)
my32BitUnsignedInteger[1] = (byte) ((secondsSince1900 & 0x0000000000FF0000L) >> 16);
my32BitUnsignedInteger[2] = (byte) ((secondsSince1900 & 0x000000000000FF00L) >> 8);
my32BitUnsignedInteger[3] = (byte) ((secondsSince1900 & 0x00000000000000FFL); // no shift needed
Наша my32BitUnsignedInteger
теперь эквивалентна 32-разрядному целому числу с прямым порядком байтов без знака, которое соответствует стандарту RCF 868. Да, длинный тип данных подписан, но мы проигнорировали этот факт, потому что предполагали, что секундаSince1900 использовала только младшие 32 бита). Из-за перевода длинного в байт все биты выше 2 ^ 7 (первые две цифры в шестнадцатеричном формате) будут игнорироваться.
Источник ссылки: Java Network Programming, 4-е издание.