Alex Rivera | Logout

Java generics code compiles with javac, fails with Eclipse Helios

Asked 2010-08-10T19:53:54.823
9

I have the following test class that uses generics to overload a method. It works when compiled with javac and fails to compile in Eclipse Helios. My java version is 1.6.0_21.

All the articles I read indicate that Eclipse is right and this code should not work. However when compiled with javac and run, the right method is selected.

How is this possible?

Thanks!

import java.util.ArrayList;

public class Test {
    public static void main (String [] args) {
        Test t = new Test();
        ArrayList<String> ss = new ArrayList<String>();
        ss.add("hello");
        ss.add("world");
        ArrayList<Integer> is = new ArrayList<Integer>();
        is.add(1);
        is.add(2);
        System.out.println(t.getFirst(ss));
        System.out.println(t.getFirst(is));
    }   
    public String getFirst (ArrayList<String> ss) {
        return ss.get(0);
    }
    public Integer getFirst (ArrayList<Integer> ss) {
        return ss.get(0);
    }
}
Edit
Report

2 Answers

4

This code is correct, as described in JLS 15.12.2.5 Choosing the Most Specific Method.

Also, consider coding to the interface:

List<String> ss = new ArrayList<String>();
List<Integer> is = new ArrayList<Integer>();
// etc.

As @McDowell notes, the modified method signatures appear in the class file:

$ javap build/classes/Test
Compiled from "Test.java"
public class Test extends java.lang.Object{
    public Test();
    public static void main(java.lang.String[]);
    public java.lang.String getFirst(java.util.ArrayList);
    public java.lang.Integer getFirst(java.util.ArrayList);
}

Note that this does not contradict @meriton's observation about the class file. For example, the output of this fragment

Method[] methods = Test.class.getDeclaredMethods();
for (Method m : methods) {
    System.out.println(Arrays.toString(m.getGenericParameterTypes()));
}

shows the formal parameter of main(), as well as the two generic type parameters:

[class [Ljava.lang.String;]
[java.util.ArrayList<java.lang.String>]
[java.util.ArrayList<java.lang.Integer>]
answered 2010-08-10T20:11:22.907
2

It would be possible if javac had a bug in it. Javac is just software and is as liable to bugs as any other piece of software.

Plus, the Java Language Spec is very complex and a little bit vague in places so it could also be down to a difference in interpretation between the Eclipse guys and the javac guys.

I would start by asking this on the Eclipse support channels. They're normally very good at picking up these things and explaining why they think they're right or else admitting that they're wrong.

For the record, I think Eclipse is right here, too.

answered 2010-08-10T19:57:32.940

Your Answer