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 ==}"提示"的第二种情况?
两个代码片段(带和不带 0==)都适用于我的 Eclipse。我正在使用 Eclipse 3.3.2 和 JDK 1.6.0_21-b07,其配置为 Eclipse 的“替代 JRE”。也许这就是它对我有用的原因。