Certain functionality of the compiler puzzles me (Oracle JDK 1.7 using Eclipse).
So I\'ve got this book that says char primitive needs to be explicitly cast to short
Basically, the specification of assignment conversion specifies that
In addition, if the expression is a constant expression (§15.28) of type byte, short, char, or int:
A narrowing primitive conversion may be used if the type of the variable is byte, short, or char, and the value of the constant expression is representable in the type of the variable.
Your '&'
is precisely "a constant expression of type byte, short, char, or int".
This is called compile-time narrowing of constants. It is described in section 5.2 of the Java Language Specification:
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.
Same goes for character literals: if its value fits in a byte
, no conversion is required; if the value does not fit, you must put in a cast, or you would get a compile error.
For example, this would not compile:
byte bc = '\uff12'; // Does not compile without a cast
but this compiles fine:
byte bc = (byte)'\uff12';
The expression '&' that is in your initializer for variable bc is a constant expression. The expression c that is in your initializer for variables b and s is not a constant expression. Java performs implicit narrowing conversions of primitives when the context requires it when the value is the result of a constant expression only.
I don't know this explaination is enough or not, but this behavior is defined in the JLS. From the JLS, section 5.2:
In addition, if the expression is a constant expression (§15.28) of type byte, short, char or int :
- A narrowing primitive conversion may be used if the type of the variable is byte, short, or char, 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 type byte.
- Short and the value of the constant expression is representable in the type short.
- Character and the value of the constant expression is representable in the type char.
Why does the following work as well?
Because '&'
is a constant expression whose value fits in byte
.
JLS 14.4.2
If a declarator has an initialization expression, the expression is evaluated and its value is assigned to the variable.
JLS 5.2
Assignment conversion occurs when the value of an expression is assigned (§15.26) to a variable: the type of the expression must be converted to the type of the variable.
....
In addition, if the expression is a constant expression (§15.28) of type byte, short, char, or int:
- A narrowing primitive conversion may be used if the type of the variable is byte, short, or char, and the value of the constant expression is representable in the type of the variable.