8
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;
  }
}

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

4

2 回答 2

5

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

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

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

于 2013-09-25T07:40:22.063 回答
2

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

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

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

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

于 2013-09-25T07:32:21.793 回答