I'm not sure that I understand overloading of generic methods.
The spec says in section 5.6.1, page 15:
"Overload resolution changes in several ways due to genericity and covariant return types. In particular: The existing specification assumes that if there are multiple candidate methods with the same signature, they all have the same return type. This is no longer the case.
...
If more than one member method is both accessible and applicable to a method invocation, it is necessary to choose one to provide the descriptor for the run-time method dispatch. The Java programming language uses the rule that the most specific method is chosen."
Why is the following illegal then?
public class Test {
private static class someClass implements Cloneable {
}
private static <T> T f() {
return null;
}
private static <T extends someClass> T f() {
return null;
}
private static <T extends Cloneable> T f() {
return null;
}
private static void test1() {
someClass d = null;
String s = null;
Cloneable c = null;
d = f();
s = f();
c = f();
f();
}
public static void main(String[] args) {
test1();
}
}
The compiler complains about ambiguous method calls when I invoke f(), no matter how I invoke it. Why doesn't it pick the most specific method?
In the example of
someClass d = f();
the compiler must infer the type parameter, which in this case would be T:=someClass. And then I would think that
<T extends someClass> T f()
is the most specific method.
The spec describes what "more specific" means, but only for methods that have arguments, as far as I understand it. What does it mean for methods without arguments?
In the example of
String s = f();
the compiler would infer T:=String. And then there is only one viable candidate, namely
<T> T f()
. The compiler does not even have to decide which candidate is the most specific one, and still it complains about an ambiguity. Why?
I would perhaps understand it if the compiler rejected the method definitions as duplicates in the first place, because you cannot overload methods that only differ in their return types. But that's not what it does.
I'm sure I'm missing something essential here. What is it? Does anybody have any idea?