JDK 1.7打破向后兼容性? (泛型)

时间:2013-09-04 12:14:40

标签: java generics java-7 java-6

我发现了类似的主题,但过于复杂且不完全相同。事情就是这样。这是(最小)代码,在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

2 个答案:

答案 0 :(得分:13)

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

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

至于让它在1.7中运行,我相信重新分解是你唯一的选择。

答案 1 :(得分:6)

这是javac中已经在Java 7中修复的错误之一 - 您可以在release notes中找到更多信息。如果你想切换到Java 7,我担心你唯一的选择就是重写代码。

  

区域:工具
  概要:一个类不能定义两个具有相同删除签名但两种不同返回类型的方法
  描述:无论返回类型是否相同,类都无法定义具有相同擦除签名的两个方法。这是从JLS,Java SE 7 Edition,第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下被拒绝。