Consider following statement:
byte by = 5; //works fine
literal \'5\' is of type int and small enough to fit into a variable of type byt
In the integer version, the compiler knows that all the data in the number 5
can be stored in a byte
. No information is lost. That's not always true for floating point values. For example, 0.1f
isn't equal to 0.1d
.
Now for the example, you've given, the decimal value 5.5 is exactly represented in both float
and double
, so you could argue that in that case, no information is lost - but it would be pretty odd for the language specification to have to make this valid:
float f = 5.5;
but this invalid:
float f = 5.6;
The language specification is happy to talk about whether a number fits within the range of float
/double
(although even that isn't as simple as you might expect) but when it comes to whether a literal can be exactly represented, I don't think it ever goes into detail.
The easy answer is, because the specification says so (compile-time constants of type integer can be assigned to smaller types as long as they fit).
With floating-point however, there is not so much determining whether the constant fits, but rather the loss of precision that comes along with it. E.g. assigning 1.23456789123 to a double is fine, but to a float is not. It's not so obvious why, in this case, though, at least to some programmers. I'd definitely count it as a surprise when some floating-point constants work while others won't and the reason isn't as clear as with integral types (where the limits are often second nature to most).
Note that even with doubles there sometimes is lost information. You can make your constants as precise as you want, but you won't always get the exact value you stated in the variable.
Agreed with Jon, However, I would like to add that
byte by = 5; //works fine until the number is less than 128
This is because one byte can only hold upto -128 to 127. Once you will try to enter number above 127, you will get the same error like you get when storing double value into float.
byte by = 128; //compilation error
So for agreeing the lost of the conversion data, you need to perform the explicit conversion.
byte by = (byte) 128; // work fine
Perhaps the most significant reason that Java makes allowance for implicit narrowing conversions of literals of type int
to short
and byte
, but does not do so for conversions of literal double
values to float
is that Java includes float
literals, but does not allow literals of types byte
and short
.
Personally, I really dislike Java's numerical conversion rules, but the allowance for storing integer constants to short
and byte
makes those types at least somewhat bearable.