Since version 1.0, Java's type system has remained pretty much the same when it comes to primitive types: we have signed short (16 bits), int (32 bits), and long (64 bits), but no unsigned counterparts to these.
This is rarely a problem, but sometimes it might seem to be: especially when reading and writing binary data formats that use unsigned values.
ByteBuffer buf = ... int unsignedIntValue = buf.getInt();
Whenever the unsigned value is greater than Integer.MAX_VALUE, our variable unsignedIntValue will look like a negative number - since Java uses the common approach of representing signed values in two's complement encoding. But as long as we don't have to know the actual value, we don't have to care. Java doesn't change the bits if we don't ask it to, and writing out the number again will result in the exact same bytes as our previous input (if we make sure to use the same byte order, of course):