If I write something like this
System.out.println(18);
Which type has the ’18’? Is it int or byte? Or doesn’t it have a type yet?
It can’t be int, because something like this is correct:
byte b = 3;
And this is incorrect:
int i = 3; byte bb = i; //error!
EDIT: I think I found the right part in the spec at Assignment Conversion :
The compile-time narrowing of constants means that code such as:
byte theAnswer = 42;
is allowed. Without the narrowing, the fact that the integer literal 42 has type int would mean that a cast to byte would be required:
byte theAnswer = (byte) 42; // cast is permitted but not required
Advertisement
Answer
This
18
is known as an integer literal. There are all sorts of literals, floating point, String
, character, etc.
In the following,
byte b = 3;
the literal 3
is an integer literal. It’s also a constant expression. And since Java can tell that 3
fits in a byte
, it can safely apply a narrowing primitive conversion and store the result in a byte
variable.
In this
int i = 3; byte bb = i; //error!
the literal 3
is a constant expression, but the variable i
is not. The compiler simply decides that i
is not a constant expression and therefore doesn’t go out of its way to figure out its value, a conversion to byte
may lose information (how to convert 12345
to a byte
?) and should therefore not be allowed. You can override this behavior by making i
a constant variable
final int i = 3; byte bb = i; // no error!
or by specifying an explicit cast
int i = 3; byte bb = (byte) i; // no error!