当前位置: 首页 > 知识库问答 >
问题:

Maven编译器与Eclipse编译器泛型的区别?

康弘义
2023-03-14

当我从Eclipse构建到maven构建时,我发现了项目中的许多问题。我使用2.5.1编译器插件。

JDK是开放的-JDK-7

我在一个新项目中隔离了这个问题,并对其进行了深入研究。问题是:

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;
}
}

这无法使用javaC进行编译(但在Eclipse中工作),并说明以下错误:

[错误]无法执行目标组织。阿帕奇。专家插件:maven编译器插件:2.5.1:项目测试时编译(默认编译):编译失败
[错误]/home/username/workspace/projectx43/test/src/main/java/test/test。java:[11,24]错误:不兼容的类型

这将起作用:

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;
    }
}

每个人都可以看到,使用E的版本和只使用T的版本一样好。现在的问题是,我可以调整javac编译器来接受这一点吗?关于这一点的任何信息都将不胜感激。

还有另一种可能性:openJDK 7处理这个问题的方式与SunJDK 7不同吗?如果你能用最新的windows Sun JDK 7版本甚至JDK 8的测试版来验证这个片段。非常感谢。

PS:我读到了Eclipse和JavaC泛型之间的问题,相关的bug正在被解决。

共有1个答案

宰父玄天
2023-03-14

我记得2008年我们采用Java 5.0时,同样的问题也是一个问题。这与eclipse编译器处理泛型的方式略有不同有关。

如果您查看上面的示例,JavaC编译器不允许传递泛型解析。举个例子,我们来看一下:

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

JavaC在这里抱怨说sort不适用于List。

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

解决方案是引入一个变量,破坏上述表达式的美:

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

这取决于人们是否认为这是一个错误。我更喜欢Eclipse编译器版本,因为它产生更容易阅读的表达式。

 类似资料:
  • Groovy中的简单泛型类 Groovy版本: 这是我做的一个简单的测试用例,当一个更复杂的类不能编译时,错误是“不能将类型T的值赋给类型double[]的变量”。

  • 问题内容: 在关于反射的本教程中,它指出: […]因为泛型是通过类型擦除实现的,因此在编译过程中会删除有关泛型类型的所有信息 我的知识是使用泛型,以便在编译时编译器可以检查类型安全性。即失败快速方法。但是该链接提到类型擦除会在编译期间删除通用信息。 问题答案: 您引用的语句是正确的:编译器在编译过程中在内部使用通用类型信息,在处理源时会生成与类型相关的错误。然后,一旦完成验证,编译器将生成类型擦除

  • 在stackoverflow中还没有讨论的情况下,我遇到了“不兼容类型”编译器错误(例如,为什么这个通用java代码不能编译?)。 我的期望很简单--我调用的是一个模板化方法,它不使用包含类的任何“泛型”类,因此它应该从方法参数中提取模板参数的类型,并且在所有情况下都应该编译--但我得到了“不兼容类型”编译器错误。 我注意到解决这个问题的奇怪方法--在方法参数中向泛型datatype添加“<?ex

  • 那么,让我看看我是否明白了这一点。 > 当我们说编译器和解释器之间的区别时,解释器将高级指令翻译成中间形式,然后执行。[我认为编译器也将高级指令翻译成中间形式,但此刻它生成目标代码而不是执行它,对吗?] 解释器一次读取一条指令或一行的源代码,将该行转换为机器代码并执行它。[解释器本身不会将代码转换为机器代码,它会使用ist自己的预编译函数评估指令(在解析之后)。例如,高级语言中的Add表达式将使用

  • 本文向大家介绍编译器和汇编器之间的区别,包括了编译器和汇编器之间的区别的使用技巧和注意事项,需要的朋友参考一下 编译器 编译器用于将高级编程语言代码转换为机器级代码并创建可执行程序。编译器检查程序中的错误并报告它们。所有错误都将被清除,否则将不会编译和执行代码。 组装工 汇编程序用于将汇编级代码转换为机器可读代码。汇编程序也会检查每条指令的正确性并报告诊断报告。 以下是编译器和汇编器之间的重要区别