Originally posted by Anders Nystedt:
... I assume that the long doesn't get boxed to Long but instead narrowed to a float in order not to break compatibility with previous Java versions. But why is there no warning when I compile (or at runtime) that I will loose precision?
The Float gets widened to an Object, as far as I understand for the same reason - not to break compatibility.
The double, however, is boxed into an Object (via Double). How come? ...
Welcome to JavaRanch!
I think the confusion centers around conversions from integral to floating-point primitives. According to
JLS - 5.1.2 Widening Primitive Conversion a long to float or double is, in fact, a
widening conversion.
Widening primitive conversions do not lose information about the overall magnitude of a numeric value...
Conversion of an int or a long value to float, or of a long value to double, may result in loss of precision -- that is, the result may lose some of the least significant bits of the value. In this case, the resulting floating-point value will be a correctly rounded version of the integer value, using IEEE 754 round-to-nearest mode (�4.2.4).
So the order of widening is byte > short > int > long > float > double. (A char can be widened to type int or wider, but a byte or short cannot be widened to type char.) For widening conversions, it's up to the programmer to recognize a possible loss of precision.
Then according to
JLS - 5.3 Method Invocation Conversion...
Method invocation contexts allow the use of one of the following:
an identity conversion (�5.1.1) a widening primitive conversion (�5.1.2) a widening reference conversion (�5.1.5) a boxing conversion (�5.1.7) optionally followed by widening reference conversion an unboxing conversion (�5.1.8) optionally followed by a widening primitive conversion.
So in your example, the long is
widened to float. A double cannot be widened any further, so it is boxed to Double, and that reference is widened to Object.