15

我发现了类似的主题,但过于复杂且不完全相同。事情就是这样。这是(最小的)代码,在 1.6 上很好,但不能用 1.7 javac 编译。

public class Test {
    private static class A<T>{};
    private static class B{};
    private static class C{};

    B doSomething(A<B> arg){
        return new B();
    }

    C doSomething(A<C> arg){
        return new C();
    }
}

在 1.7 上,错误是这样的:

java: name clash: doSomething(Test.A<Test.C>) and doSomething(Test.A<Test.B>) have the same erasure

我了解类型擦除以及为什么它是错误代码。我只是不明白为什么我们的项目可以在 1.6 中编译和运行这段代码,而 1.7 有问题。怎么了?是 1.6 编译器中的一个错误,它允许我们这样做吗?除了重写之外,是否有可能让它在 1.7 中工作?

  • JDK1.6 javac版本:1.6.0_43
  • JDK1.7 javac版本:1.7.0_25
4

2 回答 2

13

你说得对,在 JLS3 下,这段代码不应该编译,这是 1.6 中的一个错误。

对于 1.7 的发布,许多底层类型系统进行了更新并修复了这个错误,结果是更好的类型处理,但代价是一些向后兼容性问题。

至于让它在 1.7 中工作,我相信重构是你唯一的选择。

于 2013-09-04T12:19:00.910 回答
6

这是 Java 7 中已修复的 javac 中的错误之一 - 您可以在发行说明中找到更多信息。如果您想切换到 Java 7,恐怕您唯一的选择就是重写该代码。

领域:工具
简介:一个类不能定义两个具有相同擦除签名但返回类型不同的方法
描述:一个类不能定义两个具有相同擦除签名的方法,无论返回类型是否相同。这来自 JLS,Java SE 7 版,第 8.4.8.3 节。JDK 6 编译器允许具有相同擦除签名但返回类型不同的方法;此行为不正确,已在 JDK 7 中修复。
示例

class A {
    int m(List<String> ls) { return 0; }
   long m(List<Integer> ls) { return 1; }
}

此代码在 JDK 5.0 和 JDK 6 下编译,在 JDK 7 下被拒绝。

于 2013-09-04T14:22:06.783 回答