Is this valid Java?
import java.util.Arrays;
import java.util.List;
class TestWillThatCompile {
public static String f(List<String> list) {
System.out.println("strings");
return null;
}
public static Integer f(List<Integer> list) {
System.out.println("numbers");
return null;
}
public static void main(String[] args) {
f(Arrays.asList("asdf"));
f(Arrays.asList(123));
}
}
- Eclipse 3.5 says yes
- Eclipse 3.6 says no
- Intellij 9 says yes
- Sun javac 1.6.0_20 says yes
- GCJ 4.4.3 says yes
- GWT compiler says yes
- Crowd at my previous Stackoverflow question says no
My java theory understanding says no!
It would be interesting to know what the JLS is saying about it.
Eclipse can produce byte code out of this:
Output:
4
15129
Well, if I understand bullet point three correctly in the first list from section 8.4.2 of the spec, it says your f() methods have the same signature:
http://java.sun.com/docs/books/jls/third_edition/html/classes.html#38649
It's the spec that really answers this question, and not the observed behavior of compiler X or IDE X. All we can say by looking at the tools is how the author of the tool interpreted the spec.
If we apply bullet three, we get:
and the signatures match, so there's a collision and the code shouldn't compile.
Java type inference (what's going on when you call static, generic methods like Array.asList) is complicated and not well-specified in the JLS. This paper from 2008 has a very interesting description of some of the issues and how it might be fixed:
Java Type Inference is Broken: How Can We Fix it?
It's valid vased on the specification.
So these are not subsignatures of eachother because the erasure of
List<String>
is notList<Integer>
and vice versa.So these two are not override-equivalent (note the iff). And the rule for overloading is:
Therefore, these two methods are overloaded and everything should work.