donald patrick wrote:short x = 10;
short y = 3;
short z = x * y; //DOES NOT COMPILE. Reason says: "because x and y are automatically promoted to int. And then setting a short variable to an int is a compile error.
donald patrick wrote:
However,
short a = 10 * 3; //DOES COMPILE??? Why? exactly. Documentation says "literals are all interpreted as integers". So, 10 and 3 are integers. Yet, for "some" reason that line compiles?
Stephan van Hulst wrote:When the variables are final, the compiler can reason that they will never change, and so it's safe to inline the values wherever the variable appears in the code. Arithmetic operations on constants can be performed at compile time to further improve the code. If the resulting value is within range, it can safely be assigned.
Henry Wong wrote:Nope. The "effectively final" rule can't be used to replace the "final" declaration requirement for constant variables... so, with Java 8, it is still not a compile time constant without the "final" declaration.
Campbell Ritchie wrote:
At least I think that is what the situation is.
Maybe they will in Java11. You have a good point there.Stephan van Hulst wrote:. . . If they can be used in lambda expressions, then why aren't they inlined, and why aren't operators optimized away?
The secret of how to be miserable is to constantly expect things are going to happen the way that they are "supposed" to happen.
You can have faith, which carries the understanding that you may be disappointed. Then there's being a willfully-blind idiot, which virtually guarantees it.
Why? You have three compile time constant ints constituting an expression which evaluates to an int in the range of a byte. The previous example with a long wouldn't compile because it isn't an int. Your version with + 1 evaluates to 128, outwith the range of a byte, that won't compile.Tim Holloway wrote:. . .
Will probably fail . . .
The secret of how to be miserable is to constantly expect things are going to happen the way that they are "supposed" to happen.
You can have faith, which carries the understanding that you may be disappointed. Then there's being a willfully-blind idiot, which virtually guarantees it.
Hence although 32767 fits in the range of short implicit narrowing conversion doesn't take place because of long which is omitted in the above given rule.JLS 9 5.2 Assignment Contexts wrote:Assignment contexts allow the value of an expression to be 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 variable is of type byte, short, or char, and the value of the constant expression is representable in the type of the variable.
No, it means the compiler can calculate the value of the expression before the code is compiled. The variable that expression is assigned to might change later. In certain circumstances it means that the compiler can be confident that its value will fit into a narrower datatype, e.g. a byte.donald patrick wrote:. . . Compile time constant helps Java know for certain that the variable will not change.
That is neither a narrowing conversion nor a widening conversion. It is a conversion to the same type. You can always convert an int to an int.. . . That's why I used (int)127 . . .
It doesn't match the rules you were shown earlier from the Java® Language Specification.I then used long(32767) . . . But clearly there is something special about casting with (long). . . .
Don't know. It is probably because the compiler is so programmed that a cast to long means you are saying you want the number not to be an int, a short, a char or a byte. Whichever it is, that is how the JLS was written and assigning a long to a smaller datatype is not permissible.But, why?
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime. |