Aquí hay buenas respuestas, pero no veo ninguna demostración de operaciones bit a bit. Como dice Visser (la respuesta actualmente aceptada), Java firma enteros por defecto (Java 8 tiene enteros sin signo, pero nunca los he usado). Sin más preámbulos, hagámoslo ...
RFC 868 Ejemplo
¿Qué sucede si necesita escribir un entero sin signo en IO? Un ejemplo práctico es cuando desea generar el tiempo de acuerdo con RFC 868 . Esto requiere un número entero de 32 bits, big-endian, sin signo que codifique el número de segundos desde las 12:00 AM del 1 de enero de 1900. ¿Cómo codificaría esto?
Haga su propio entero de 32 bits sin signo como este:
Declarar una matriz de bytes de 4 bytes (32 bits)
Byte my32BitUnsignedInteger[] = new Byte[4] // represents the time (s)
Esto inicializa la matriz, consulte ¿Las matrices de bytes se inicializan a cero en Java? . Ahora tiene que llenar cada byte en la matriz con información en el orden big-endian (o little-endian si quiere causar estragos). Suponiendo que tiene un tiempo que contiene el tiempo (los enteros largos son de 64 bits en Java) llamado secondsSince1900
(que solo utiliza los primeros 32 bits, y ha manejado el hecho de que Date hace referencia a las 12:00 AM del 1 de enero de 1970), luego puede usar el AND lógico para extraer bits de él y cambiar esos bits a posiciones (dígitos) que no se ignorarán cuando se conviertan en un Byte, y en orden big-endian.
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
Nuestro my32BitUnsignedInteger
ahora es equivalente a un entero big endian sin signo de 32 bits que se adhiere al estándar RCF 868. Sí, el tipo de datos largo está firmado, pero ignoramos ese hecho, porque asumimos que los segundosSince1900 solo usaron los 32 bits inferiores). Debido a convertir el largo en un byte, se ignorarán todos los bits superiores a 2 ^ 7 (primeros dos dígitos en hexadecimal).
Fuente referenciada: Java Network Programming, cuarta edición.