在java 7中编译时名称冲突编译错误,但在java 5中工作正常

Dra*_*gon 8 java compiler-errors

public interface Expression {

}

public interface ArithmeticExpression extends Expression {

}


public class StaticMethodDemo {
  public static void print(Expression e) {
    System.out.println("StaticMethodDemo");
  }

  public static List<Expression> convert(
        Collection<? extends Expression> input) {
    return null;
 }
}


public class StaticMethodChild extends StaticMethodDemo {

    public static void print(ArithmeticExpression e) {
    System.out.println("StaticMethodChild");
   }

   public static List<ArithmeticExpression> convert(
        Collection<? extends ArithmeticExpression> input) {
    return null;
  }
}
Run Code Online (Sandbox Code Playgroud)

上面的代码在java 5中编译但在java 7中没有编译为什么?在java 7中,它给出了"Name clash:StaticMethodChild类型的方法convert(Collection)与StaticMethodDemo类型的convert(Collection)具有相同的擦除,但不隐藏它"

aay*_*ubi 5

除了 Stonedsquirrel 的回答,即使方法不是静态的,你也会得到同样的错误。

这是因为类型擦除,您将尝试使用不兼容的类型覆盖转换。

检查以下答案以获得很好的解释。


And*_*nek 2

Java 不允许重写静态方法。请参阅为什么 Java 不允许重写静态方法?

您唯一能做的就是在子类中隐藏静态方法。隐藏意味着它不依赖于调用什么类型的对象,而是依赖于什么类型的类。请参阅http://docs.oracle.com/javase/tutorial/java/IandI/override.html

现在的问题是,您的子类方法在形式上具有相同的签名,但由于泛型类型,它并没有隐藏它。Collection<? extends ArithmeticExpression>既不是相同的,也不是Collection<? extends Expression>实际上阻止正确、明确隐藏的子类型。正如 Ayobi 指出的,引入编译器规则是为了确保向后兼容性:方法与类型中的另一个方法具有相同的擦除

现在无法亲自尝试,但当两者具有相同的泛型类型时,错误应该消失。虽然我不知道为什么在 Java 5 中不会出现该错误。我猜他们在更高版本中引入了该编译器规则,因为他们之前没有注意到它。