I want to create two functions, say
long min(long...);
int min(int...);
But when I try to invoke the second i.e min(1, 5)
one I get ambiguous method call
Is there workaround except renaming?
I want to create two functions, say
long min(long...);
int min(int...);
But when I try to invoke the second i.e min(1, 5)
one I get ambiguous method call
Is there workaround except renaming?
The problem is when you invoke those method with an
integer
, none of the methods provide exact match for the argument, as you usedvar-args
. Also, both thevar-args
can takeint
values separated by commas as argument. Hence theambiguous method
error.When you call overloaded method,
Compiler
chooses theexact match
first. Then thenearest type
to cast.Now, since
var-args
is just anarray
, compiler cannot decide which array to use while passing aninteger
value. As, neither arrays can be considered asexact match
ornearest conversion
. So, it takes both the method eligible for call.There are lot more rules regarding the
method invocation
in case ofOverloading
. You can learn those from theJava Language Specification
.As in @assylias answer this problem has been fixed in Java 7. But it will not work in Java version < 7.
It is a known bug
The behaviour you describe is a bug which has been fixed with Java 7. See details in the release notes, section called "Changes in Most Specific Varargs Method Selection".
The reason why it should compile
Variable arity comes last in determining the most specific method. The rules to determine which vararg method applies when there are several are defined in JLS 15.12.2.4 - here is an extract:
In your case, k = n, and
U1[] = int[]
andT1[] = long[]
so the determination can be made ifint <: long
or the opposite.In other words, the type taken into account is not
int[]
vs.long[]
butint
vslong
. And it happens thatint <: long
so theint...
method should be chosen and it should compile.Conclusion:
The code should (and does) compile fine with Java 7 but would not compile with Java 5 or 6. The code below prints
int
with Java 7:Those method signatures are unique, and are valid method overloads.
The problem must be in the method call argument. My guess is that you are calling the method with a literal, like:
And it doesnt like that because 100 is an integer literal, but it gets automatically converted to a long.
disambiguating the method calls by using L at the end of long literals should fix the problem:
Also, you could make the calls explicit by using the Java Object Integer and Long, and let autoboxing take care of the conversion to primitive types:
Try this