【问题标题】:If static methods cannot be overriden, why must they satisfy the exception throws contract of the static method in the parent? [duplicate]如果静态方法不能被覆盖,为什么它们必须满足父类中静态方法的异常抛出协定? [复制]
【发布时间】:2016-10-21 22:51:10
【问题描述】:

由于静态函数属于一个类,它们是被继承的,但不是被覆盖的,只是被隐藏了。从下面的代码看来,B 中的 woof 方法似乎只有在父方法也有“throws IOException”声明的情况下才能有“抛出 IOException”声明。即下面的代码给出了一个编译器错误,即 throws 子句与 A.woof 中的不兼容 如果该方法没有被覆盖,为什么它必须满足异常契约?

class A {
    static void woof()  { //Compiles IF i add throws IOException here
        System.out.println("A's woof");
    }
}

class B extends A {
    static void woof() throws IOException {  //Compiler error
        System.out.println("B's woof");
    }

【问题讨论】:

  • 值得注意的是,编译器说“重写的方法不会抛出IOException”而不是“隐藏的方法不会抛出IOException”
  • 你可以重写一个异常比超类的方法少的方法,但是你不能引入新的。查找Liskov Substitution Principle
  • @MadMatts LSP 适用于子类型;这不是子类型。
  • 这可能与您可以在对象而不是类上调用静态方法这一事实有关。
  • @AndyTurner 如果这是可能的并且你有A a = new B(); ((B)a).woof();,你会得到一个IOException,而你不会用a.woof()。这不违反原则吗?

标签: java inheritance static


【解决方案1】:

此行为已在 JLS 规范中捕获。看起来覆盖和隐藏方法被编译器以相同的方式处理。

更准确地说,假设 B 是一个类或接口,而 A 是一个 B 的超类或超接口,以及 B 中的方法声明 m2 覆盖或隐藏 A 中的方法声明 m1。然后:

如果 m2 有一个 throws 子句提及任何已检查的异常类型,则 m1 必须 有 throws 子句,或发生编译时错误。

对于每个 在 m2 的 throws 子句中列出的检查异常类型,相同 异常类或其超类型之一必须出现在擦除中 (§4.6) m1 的 throws 子句;否则,编译时错误 发生。

如果 m1 的未擦除 throws 子句不包含 m2 的 throws 子句中每个异常类型的超类型(改编, 如有必要,给 m1) 的类型参数,一个编译时 unchecked 出现警告。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-15
    • 2011-09-16
    • 2014-09-28
    • 2017-10-06
    • 1970-01-01
    • 2011-11-16
    • 1970-01-01
    • 2012-07-03
    相关资源
    最近更新 更多