奇怪的行为围绕“相同的擦除”编译错误
我最近偶然发现了一段代码,由于“相同的擦除”问题,这段代码在我的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 {
}
}
带有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
它编译。 我检查了1.6.0_21和1.6.0_06(他们在他们的环境中的那个人),但都没有抱怨。 我将类文件复制到Eclipse期望的位置,并强制它再次运行它。
它打印:
has done something to Collection<A>
true
如果我更换
System.out.println(0 == GenericsTest.doSomething(new ArrayList<C>()));
同
System.out.println(GenericsTest.doSomething(new ArrayList<C>()));
它仍然会在没有来自命令行的警告的情况下进行编译,但在尝试运行时会给出相同的“未解决的编译问题”。
这里有两个问题。
javac是否超越了内置的Eclipse编译器? 看起来几乎完全像这个以前问的问题,所以我相信我知道答案。 (顺便说一句,我如何告诉Eclipse使用javac呢?)。
为什么javac会静静地编译java然后运行失败(第二种情况是{0 ==}“提示”被删除?
根据Java规范,应该通过签名(名称+参数类型)区分两种方法,而不是返回类型。 由于JDK中的一个bug,可以编译原始代码http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6182950在某些版本的Eclipse中已修复此错误,这就是为什么有些人无法获得它在Eclipse中编译。 至于为什么编译后的代码能够真正起作用,您应该了解Java语言不等同于JVM字节码。 在字节码中,你可能有很多非法的Java名字,是的,字节码通过签名,返回类型和可能的一些附加信息来区分方法。
这里的问题是:每当你有两个同名的方法时,它们必须有不同的签名。 这里考虑的签名不包括返回类型,所以这两个方法不能在同一个类中声明
int foo(A a)
float foo(A a)
在你的例子中,你有两个具有不同参数类型的不同方法( Collection<A>
和Collection<C>
),但在内部,当编译器发挥它的魔力时,泛型被认为是Collection。 这就是“同样的删除”的含义。
现在我不记得了,如果所有的java版本都显示这种行为,因为我一直被java 5和java 6卡住了太多。
希望它可以帮助。
帕维尔,我想我面临着你所描述的同样的问题。
今天,我用自己的代码进行黑客攻击,并获得了Eclipse和Java编译器相同的不同行为。 虽然,它似乎是一个已知的编译器问题。
请参阅Bug 6182950。
谢谢!
链接地址: http://www.djcxy.com/p/48513.html