I'm trying to understand the narrowing primitive conversion concept in Java. Here's what the JLS 5.1.3 says about it:
22 specific conversions on primitive types are called the narrowing primitive conversions:
short to byte or char
char to byte or short
int to byte, short, or char
long to byte, short, char, or int
float to byte, short, char, int, or long
double to byte, short, char, int, long, or float
Since there is the implicit conversion converting long
to int
, we can write the following code:
public static void main (String[] args) throws java.lang.Exception
{
int c = 88L; //Compilation fail
System.out.println(c);
}
But it doesn't work. Why? The narrowing conversion from long to int should have been applied.
Since there is the implicit conversion converting long to int
There isn't. There's an explicit conversion. Narrowing conversions aren't generally applied implicitly, precisely because they can lose information. So you'd need:
int c = (int) 88L;
Indeed, the initial part of JLS section 5 even gives an example:
// Casting conversion (5.4) of a float literal to
// type int. Without the cast operator, this would
// be a compile-time error, because this is a
// narrowing conversion (5.1.3):
int i = (int)12.5f;
There are some cases where narrowing conversions are applied explicitly in assignment contexts (JLS 5.2) though:
In addition, if the expression is a constant expression (ยง15.28) of type
byte
,short
,char
, orint
:
A narrowing primitive conversion may be used if the type of the variable is
byte
,short
, orchar
, and the value of the constant expression is representable in the type of the variable.A narrowing primitive conversion followed by a boxing conversion may be used if the type of the variable is:
Byte
and the value of the constant expression is representable in the typebyte
.... (similar for
Short
andCharacter
)
That's why this is valid even though the type of the literal 120
is int
:
byte x = 120;
Compare that with widening conversions, which are permitted within assignment contexts and invocation contexts (JLS 5.3).
See more on this question at Stackoverflow