The outputs to all the no_min_arg() invocations make sense to me but I'm unable to justify why the 2 invocations to one_min_arg() result in an error and how is it different from the type casting that occurs while invoking no_min_args().
void no_min_args(float... args)
{
System.out.println("no_min_args 1st function");
}
void no_min_args(double... args)
{
System.out.println("no_min_args 2nd function");
}
void one_min_arg(float f, double... args)
{
System.out.println("one_min_arg 1st function");
}
void one_min_arg(double d, float... args)
{
System.out.println("one_min_arg 2nd function");
}
void driver_func()
{
no_min_args(1); //Output: no_min_args 1st function
no_min_args(1.5f); //Output: no_min_args 1st function
no_min_args(1.5); //Output: no_min_args 2nd function
one_min_arg(1); //Output: Error: reference to one_min_arg is ambiguous
one_min_arg(1.5f); //Output: Error: reference to one_min_arg is ambiguous
one_min_arg(1.5); //Output: one_min_arg 2nd function
}
For one_min_arg(1.5)
, only the (double, float...)
overload is applicable. 1.5
is a double
and so is not compatible with the float
parameter of the other overload. So there is no ambiguity.
In other two cases, both overloads are applicable. 1
is an int
and so is compatible with either double
or float
parameter. 1.5f
is a float
, and is also compatible with either a double
or float
parameter.
So now Java needs to choose the most specific overload out of the two. The situation is similar to no_min_args(1)
and no_min_args(1.5f)
. In those cases, Java chooses the (float...)
overload as the most specific, because float
is more specific than double
(float
is a subtype of double
as per JLS §4.10).
In the cases of one_min_arg
however, neither overload is more specific than the other. This is because Java considers the types of both of the parameters of each overload, even if you do not pass any arguments corresponding to the variable arity parameter.
The relevant quote from the language specification is:
One applicable method
m1
is more specific than another applicable methodm2
, for an invocation with argument expressionse1
, ...,ek
, if any of the following are true:
- [...]
- [...]
m2
is not generic, andm1
andm2
are applicable by variable arity invocation, and where the firstk
variable arity parameter types ofm1
areS1
, ...,Sk
and the firstk
variable arity parameter types ofm2
areT1
, ...,Tk
, the typeSi
is more specific thanTi
for argumentei
for all i (1 ≤ i ≤ k). Additionally, ifm2
hask+1
parameters, then thek+1
'th variable arity parameter type ofm1
is a subtype of thek+1
'th variable arity parameter type ofm2
.
Although the first parameter type of the first overload (float
) is more specific than the first parameter type of the second overload (double
), the part after "Additionally" does not hold. In this case, k
is 1, and the two overloads both have 2 (k + 1
) parameters. The variable arity parameter type of the first overload (double
) is not a subtype of the variable arity parameter type of the second overload (float
). Therefore, the first overload is not more specific than the second overload.
The second overload is also not more specific than the first overload, because of the types of their first parameters (double
is not more specific than float
).
So neither overload is more specific than the other, so there is no most specific overload.
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