I'm doing my Java class exercises. I have this code which contains an overloaded method:
class A {
// Overloaded method
public void f(int n, float x) {
System.out.println("f(int n, float x) n = " + n + " x = " + x);
}
private void f(long q, double y) {
System.out.println("f(long q, double y) q = " + q + " y = " + y);
}
public void f(double y1, double y2) {
System.out.println("f(double y1, double y2) y1 = " + y1 + " y2 = " + y2);
}
public void g() {
int n = 1;
long q = 12;
float x = 1.5f;
double y = 2.5;
System.out.println("--- dans g ");
f(n, q);
f(q, n);
f(n, x);
f(n, y);
}
}
Main:
public static void main(String[] args){
A a = new A() ;
a.g() ;
System.out.println ("--- dans main") ;
int n=1 ;
long q=12 ;
float x=1.5f ;
double y = 2.5 ;
a.f(n, q) ; // my problem is here
a.f(q, n) ;
a.f(n, x) ;
a.f(n, y) ;
}
When I call the method a.f(n,q)
in main I expect an error, but it calls the method f(int n, float x)
while my q
is a long
number and it's size is bigger then a float
's size (8 byte / 4 byte) So I wonder how these primitive types works?
Method invocations occupy a pretty length chunk of the spec. To summarize, the compiler proceeds as follows:
Step 2 is the most interesting one here: this proceeds in a number of steps. To summarize:
You're supplying parameters that don't exactly match any of the parameter types of the overloads, so you need check if you can convert that parameters to allow strict invocation. The conversions in strict invocations are:
- an identity conversion (§5.1.1)
- a widening primitive conversion (§5.1.2)
- a widening reference conversion (§5.1.5)
An int
can be converted by identity conversion to int
. A long
can be converted by widening primitive conversion to a float
.
Hence f(int, float)
is applicable.
f(long, double)
and f(double, double)
are also applicable, since int
can be widened to long
and double
; and long
can be widened to double
.
However, these are less specific than f(int, float)
, since int
can be widened to long
and double
, and float
can be widened to double
. Hence, by the informal intuition laid out in JLS Sec 15.12.2.5, these methods are less specific than f(int, float)
. As such, f(int, float)
is the one that is invoked.
longs
can be converted to float
without raising errors. But you may lose precision.
For details see the specs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With