Are there any real life uses for the Java _signed_ byte primitive type?
For some inexplicable reason the byte
primitive type is signed in Java. This mean that valid values are -128..127 instead of the usual 0..255 range representing 8 significant bits in a byte (without a sign bit).
This mean that all byte manipulation code usually does integer calculations and end up masking out the last 8 bits.
I was wondering if there is any real life scenario where the Java byte
primitive type fits perfectly or if it is simply a completely useless design decision?
EDIT: The sole actual use case was a single-byte placeholder for native code. In other words, not to be manipulated as a byte inside Java code.
EDIT: I have now seen a place where an inner tight loop needed to divide by 7 (numbers 0..32) so a lookup table could be done with bytes as the datatype so the memory usage could be kept low thinking of L1 cache usage. This does not refer to the signed/unsignedness but was a case of an actual usage.
Josh Bloch recently mentioned in a presentation that this is one of the mistakes in the language.
I think the reason behind this is that java does not have unsigned numeric types, and byte
should conform to that rule. (Note: char
is unsigned, but does not represent numbers)
As for the particular question: I can't think of any example. And even if there were examples, they would be fewer than the ones for 0..255, and they could be implemented using masking (rather than the majority)
byte, short, char
types are mostly useless, except when used in arrays to save space.
Neither Java or JVM has any real support for them. Almost all operations on them will promote them to int
or long
first. We cannot even write something like
short a=1, b=2;
a = a + b; // illegal
a = a << 1; // illegal
Then why the heck even bother with defining operations on byte, short, char
types at all?
All they do are sneaking in widening conversions that will surprise the programmer.
Amazingly, I just used byte
in Java for the first time last week, so I do have an (albeit unusual) use-case. I was writing a native Java function, which lets you implement a function in a library that can be called by Java. Java types need to be converted to types in the native language, in this case C
The function needed to take an array of bytes, but (forgetting about the byte
type entirely at the time) I had it take a char[]
. The signature Java generates for the C function gives the type of that parameter as jcharArray
, which can be converted to a bunch of jchar
s, which are typedef-ed in jni.h
to unsigned short
. Naturally, that is not the same size -- it's 2 bytes instead of 1. This caused all sorts of problems with the underlying code. Making the Java type byte[]
resulted in a jbyteArray
, and jbyte
on Linux is typedef-ed to signed char
, which is the right size
Digitized sound (or any other signal) with 8 bit signed samples seems like the only reasonable example to me. Of course having signed bytes is no requirement to handling such signals and it can be argued whether Java byte "fits perfectly".
Personally I think not having unsigned is a mistake. Not only because there's more use for unsigned bytes/ints but because I prefer a stronger type system. It would be nice to be able to specify that negative numbers are not valid and allow compiler checks and runtime exceptions for violations.