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
m1is more specific than another applicable methodm2, for an invocation with argument expressionse1, ...,ek, if any of the following are true:
- [...]
- [...]
m2is not generic, andm1andm2are applicable by variable arity invocation, and where the firstkvariable arity parameter types ofm1areS1, ...,Skand the firstkvariable arity parameter types ofm2areT1, ...,Tk, the typeSiis more specific thanTifor argumenteifor all i (1 ≤ i ≤ k). Additionally, ifm2hask+1parameters, then thek+1'th variable arity parameter type ofm1is 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