Reputation: 7212
SSCCE:
public class Test {
public static void main(String[] args) {
Long a = new Long(1L);
new A(a);
}
static class A {
A(int i) {
System.out.println("int");
}
A(double d) {
System.out.println("double");
}
}
}
Output:
double
There will be no compilation error printed, it works fine and calls double
-parameter constructor. But why?
Upvotes: 3
Views: 1590
Reputation: 26185
Converting long
to int
is a narrowing primitive conversion because it can lose the overall magnitude of the value. Converting long
to double
is a widening primitive conversion.
The compiler will automatically generate assignment context conversion for arguments. That includes widening primitive conversion, but not narrowing primitive conversion. Because the method with an int
argument would require a narrowing conversion, it is not applicable to the call.
Upvotes: 2
Reputation: 4476
int
is of 4 bytes where as long
and double
are of 8 bytes
So, it is quite obvious that there is a chance for loss of 4 bytes of data if it is casted to an int. Datatypes are always up casted. As the comment from @Bathsheba mentioned, there is a chance of data loss even in case of using double, but the loss is much smaller when compared with int.
As you can see, double uses 52 bits for storing significant digits. Where as if it chooses int, the variable will have 32 bits available to it. Hence jvm chooses the double instead of int.
Source: Wikipedia
Upvotes: 2
Reputation: 146
Because a long doesn't "fit" in an int.
Check https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html
Upvotes: 1
Reputation: 234875
It's down to the rules of type promotion: a long
is converted to a double
in preference to an int
.
A long
can always fit into a double
, although precision could be lost if the long
is larger than the 53rd power of 2. So your compiler picks the double
constructor as a better fit than the int
one.
(The compiler doesn't make a dynamic check in the sense that 1L
does fit into an int
).
Upvotes: 9