The following seemingly trivial problem has shaken the core of my understanding on how primitives work in Java.
I have come across the term "implicit narrowing"
whereby a variable of a smaller-range type is allowed to hold a literal value of a larger-range type, if that value falls within that smaller-range.
As I know, Java permits that only among byte, char, short, and int.
For example, a byte variable CAN take an int if that value is small enough to fit the range of the byte type.
byte b1 = 3; // allowed even though 3 is an int literal
byte b2 = 350; // compilation error because a byte cannot go beyond positive 127
So, this works fine:
byte k = 3;
But I don't know why the line below does not work!!
Byte k = new Byte(3);
Unless I change the latter to Byte k = new Byte((byte)3)
, I get this compilation error:
error: no suitable constructor found for Byte(int)
Byte k = new Byte(3);
^
constructor Byte.Byte(byte) is not applicable
(actual argument int cannot be converted to byte by method invocation conversion)
The last portion of the error message
seems to have a clue, which says:
"... actual argument int cannot be converted to
byte by method invocation conversion"
Then my question about the clue becomes:
why?! I mean, what is the difference between assigning a small int literal to a byte and passing a small int literal to a method to be captured by a method parameter of type byte?
I understand that casting would have to be used if I passed an int variable. But, I am NOT passing a variable. Rather, I am passing a small literal which the compiler should realize that it is small enough for a byte!!