围绕"相同擦除"编译错误的奇怪行为

Pav*_*ler 7 java generics type-erasure

我最近偶然发现了一段代码,由于"相同的擦除"问题而无法在Eclipse中编译(看起来非常类似于此问题).编写代码的人向我保证,它会在当地环境中进行编译并持续集成,因此我一直在模仿它.

看一下这个片段:

package com.mycompany.playground;

import java.util.ArrayList;
import java.util.Collection;

public class GenericsTest {

    public static void main (String[] args) {
        System.out.println(GenericsTest.doSomething(new ArrayList<A>()));
        System.out.println(0 == GenericsTest.doSomething(new ArrayList<C>()));
    }

    public GenericsTest() {
    }

    public static String doSomething(Collection<A> listOfA) {
        return "has done something to Collection<A>";
    }

    public static Integer doSomething(Collection<C> listOfC) {
        return 0;
    }

    private class A {

    }

    private class C {

    }

}
Run Code Online (Sandbox Code Playgroud)

具有1.6.0_21 JDK作为工作空间默认值的Eclipse Helios将无法编译它并且会抱怨Method doSomething(Collection)与GenericsTest类型中的另一种方法具有相同的擦除doSomething(Collection).对于另一种方法,它会说同样的话.

试图强制Eclipse运行它并看到:线程"main"中的异常java.lang.Error:未解决的编译问题:GenericsTest类型中的方法doSomething(Collection)不适用于参数(ArrayList).

好.这是可以预料的.现在.如果我进入我的命令行并运行简单:

javac GenericsTest.java
Run Code Online (Sandbox Code Playgroud)

它汇编.我检查了1.6.0_21和1.6.0_06(这些人在他们的环境中所拥有的那个)并没有抱怨.我将类文件复制到Eclipse预期的位置,并强制它再次运行它.

它打印:

has done something to Collection<A>
true
Run Code Online (Sandbox Code Playgroud)

如果我更换了

System.out.println(0 == GenericsTest.doSomething(new ArrayList<C>()));
Run Code Online (Sandbox Code Playgroud)

System.out.println(GenericsTest.doSomething(new ArrayList<C>()));
Run Code Online (Sandbox Code Playgroud)

它仍然会在没有来自命令行的警告的情况下进行编译,但在尝试运行它时会给出相同的"未解决的编译问题".

这里有两个问题.

  • javac是不是简单地超越了内置的Eclipse编译器?看起来几乎完全像以前提出的问题所以我相信我知道答案.(顺便说一句,我如何告诉Eclipse使用javac?).

  • 为什么javac会静默编译java将无法运行的内容(删除了{0 ==}"提示"的第二种情况?

Ale*_*exR 0

两个代码片段(带和不带 0==)都适用于我的 Eclipse。我正在使用 Eclipse 3.3.2 和 JDK 1.6.0_21-b07,其配置为 Eclipse 的“替代 JRE”。也许这就是它对我有用的原因。