Java泛型在Eclipse中编译,但不在javac中编译

我不得不发现我的项目中有Java代码,它在Eclipse中编译和运行良好,但在javac中抛出编译错误。

一个独立的代码段:

import java.util.HashSet;
import java.util.Set;

public class Main {

    public static void main(String[] args) {
    Set<Integer> setOfInts = new HashSet<Integer>();
    Set<Object> setOfObjects = covariantSet(setOfInts);
    }

    public static <S, T extends S> Set<S> covariantSet(Set<T> set) {
    return new HashSet<S>(set);
    }

}

javac 中的编译返回:

Main.java:10: incompatible types
found   : java.util.Set<java.lang.Integer>
required: java.util.Set<java.lang.Object>
    Set<Object> setOfObjects = covariantSet(setOfInts);
                                           ^

此错误现在阻止在 Maven 中生成项目。由于Eclipse编译器被构建为更宽容,我现在必须假设片段的定义和用法,如上面的静态方法不是有效的Java?


答案 1

看来Sun的1.6 JDK无法推断出正确的类型。以下内容似乎在我的机器上工作:

Set<Object> setOfObjects = Main.<Object, Integer>covariantSet(setOfInts);

请注意,必须调用以类名为前缀的静态方法


答案 2

你是对的。这个问题确实存在。Eclipse 不使用 .它使用自己的编译器。javac

实际上javac是“正确的”。泛型是擦除。类型不包含在字节码中,因此 jvm 在运行时没有关于返回类型的足够信息。要解决此问题,请按如下方式更改方法原型:S

public static <S, T extends S> Set<S> covariantSet(Set<T> set, Class<S> returnType)

现在,返回类型在运行时传递给方法,编译器不应抱怨。


推荐