Java strange allocation rules
short s = 'a'; // valid
short s = 'a'; // valid Short ss = 'a'; // valid int i = 'a'; // valid Integer ii = 'a'; // invalid
Why is integer II = 'a' invalid, but int i = 'a' valid? Why is short SS = 'a' valid, but integer II = 'a' invalid?
Another question:
byte b; final short s = 1; final Short ss = 1; final int i =1; final Integer ii = i; final long L = 1; final Long LL =1L; b = s; // valid b = ss; // invalid b = i; // valid b = ii; // invalid b = L; // invalid b = LL; // invalid
Why B = L; Invalid, and B = s; Does it work?
Please don't say it's all because JLS says so I want to know why JLS has these inconsistent and non intuitive rules What did I miss?
Solution
So, line:
Short s = 'a'; // is valid ...
Because char is an unsigned 16 bit value (the maximum value is 65536) and short is a signed 16 bit value (the maximum value is 32767), there is a reduced original conversion (char to short), followed by a boxing conversion (short to short))
short s = 'a'; // is valid - this is a narrowing primitive conversion (char -> short)
These are special cases:
Let's look at the next example:
Integer ii = 'a'; // is invalid - not a special case according to Oracle docs int i = 'a'; // is valid - widening primitive conversion (char -> int) is allowed
Another case comes from your question:
byte b; final long L = 1; b = L // error - incompatible types
Why is line B = l invalid? Because it is not a special case described above, we can lose information in the cast, which is why you must explicitly execute it:
b = (byte) L; // is valid - narrowing primitive conversion (long -> byte)
In addition, please take a look at the very useful table
There is a lot of information about all these rules in JLS documents. You don't need to worry about all these rules On your last question, what I can say is that if there is no implicit reduction conversion, any integer text needs to be cast in the following cases:
// Cast is permitted,but not required - profit! byte b = (byte) 100; short s = (short) 100;
Thanks to the fact that we can change it to:
byte b = 100; short s = 100;