As Jon Skeet implies in his answer, distinct literal types for byte
and short
(and char
expressed as numbers) are rarely needed. (He says that he doesn't particularly miss them, ergo ...) For the rare cases where you do need them, you can use a type cast; see below.
There are >>two<< reasons why they are not needed from the perspective of the Java language:
As noted by previous answers, arithmetic and relational operations on byte, short and char values are specified to be performed using 32 bit integer operands. Thus, when you write this:
byte b = ...
if (b > 1) {
...
}
the value of b
is promoted to an int
before comparing it with the int
value 1
. This behavior is specified in JLS 5.6 and the relevant sections of JLS Chapter 15.
You don't need to specify that 1
is a byte to compare it with a byte value ... since the comparison is done as an int.
When you assign a constant expression of type int
to a variable of types byte
, short
or char
, there is a special rule that says (in effect) that there is an implicit type cast ... if the value being assigned is in the range of the variable. For example:
byte b = 42; // OK
byte b2 = 1000; // Compilation error - out of range
byte b3 = b + 1; // Compilation error - not a constant expression
byte b4 = (byte) 42; // OK ... but redundant
This is specified in JLS 5.2
To my knowledge, the only case where you need to explicitly cast an integer literal (other than for value conversion purposes) is when you are calling a method with overloads for (say) int
and byte
arguments; e.g.
public void foo(int i) {...}
public void foo(byte b) {...}
foo(42); // binds to first overload
foo((byte) 42); // binds to second overload
As I commented on another answer, the fact that the JVM bytecodes don't support arithmetic operations on bytes, shorts and chars is an implementation detail. It is a consequence of the Java language spec's rules ... not the other way around.
How James Gosling et al reached these design decisions is not public knowledge. It happened back before Java 1.0, when the language was still called Oak. The indications are in the documentation for Oak, if you can track it down.
d
andf
and are needed to turn integer literals intodouble/float/long
literals, andl
is needed to allow an otherwise integer-looking literal to overflow the capacity of an integer. None of those reasons apply to bytes or shorts. – Rhpositive