Martin Kersten
Martin Kersten

Reputation: 5513

Maven Compiler vs Eclipse Compiler Generics Difference?

I spotted many problems in my project when I went from Eclipse build to maven build. I use the 2.5.1 compiler plugin.

JDK is open-JDK-7

I isolated the problem in a new project and stipping it down the problem is this:

public class Test {

public static void main(String[] args) {
    List<String> list = newList();
    for(String name : sort(newList(list))) {
        System.out.println(name);
    }
}

public static <T> List<T> newList() {
    return new ArrayList<T>();
}

public static <T, E extends T> List<T> newList(Collection<E> list) {
    return new ArrayList<T>();
}

public static <T> List<T> sort(List<T> list) {
    return list;
}
}

This fails to compile with javaC (but works in Eclipse) stating the following error:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.5.1:compile (default-compile) on project test: Compilation failure
[ERROR] /home/username/workspaces/projectx43/test/src/main/java/test/Test.java:[11,24] error: incompatible types

And this will work:

public class Test {

    public static void main(String[] args) {
        List<String> list = newList();
        for(String name : sort(newList(list))) {
            System.out.println(name);
        }
    }

    public static <T> List<T> newList() {
        return new ArrayList<T>();
    }

    public static <T> List<T> newList(Collection<? extends T> list) {
        return new ArrayList<T>();
    }

    public static <T> List<T> sort(List<T> list) {
        return list;
    }
}

Everyone can see that the version with E is just as good as the one using only T. The question now is, can I tweak the javac compiler to accept this. Any information about this would be appreciated.

Also another possibility: Is openJDK 7 is handling this differently to SunJDK 7? If you can please verify this snippet with the latest windows Sun JDK 7 versions or even with the beta of JDK 8. Thanks a lot.

PS: I read those Eclipse vs. JavaC + Generics questions and the Bugs linked are stating to be resolved.

Upvotes: 3

Views: 1226

Answers (1)

Martin Kersten
Martin Kersten

Reputation: 5513

I remembered the very same issue being a problem in 2008 when we adopted Java 5.0. It is just related to the fact that the eclipse compiler handles generics slightly differently.

If you check the above example the JavaC compiler does not allow transitive generics resolution. For an example lets look at this:

List<String> strings = sort(newList("A", "B", "C");

JavaC complains here saying that sort is not applicable to List.

<T> List<T> sort(List<T>) {...};
<T> List<T> newList(T ... elements) {};

The solution is to introduce a variable destroying the beauty of the expression above:

List<String> list = newList("A", "B", "C");
List<String> strings = sort(list);

It depends whether one expect this to be an error or not. I like the Eclipse compiler version better since it produces easier to read expressions.

Upvotes: 3

Related Questions