3

Since static functions belong to a class, they are inherited but not overridden, merely hidden. From the code below, it seems that the woof method in B can only have a "throws IOException" declaration if the parent method also has it. I.e the below code gives a compiler error that the throws clause is not compatible with the one in A.woof If the method is not being overridden, why must it satisfy the exception contract ?

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");
    }
  • It is worth noting that the compiler says *"overridden method does not throw IOException"* and not *"hidden method does not throw IOException"*. – RaminS Oct 21 '16 at 22:59
  • You can override a method with less exceptions than the method of the super class, but you can't introduce new ones. look up the [Liskov Substitution Principle](http://stackoverflow.com/questions/56860/what-is-the-liskov-substitution-principle) – Mad Matts Oct 21 '16 at 23:00
  • @MadMatts LSP applies to subtyping; this isn't subtyping. – Andy Turner Oct 21 '16 at 23:00
  • 2
    Perhaps this has to do with the fact that you *can* call static methods on an object instead of the class. – RaminS Oct 21 '16 at 23:04
  • @AndyTurner If this was possible and you had `A a = new B(); ((B)a).woof();` you'd get an IOException where you wouldn't with `a.woof()`. Does this not break the principle? – RaminS Oct 21 '16 at 23:10

1 Answers1

1

This behaviour has been captured in the JLS spec. Looks like the overriding and hiding methods are treated the same way by compiler.

More precisely, suppose that B is a class or interface, and A is a superclass or superinterface of B, and a method declaration m2 in B overrides or hides a method declaration m1 in A. Then:

If m2 has a throws clause that mentions any checked exception types, then m1 must have a throws clause, or a compile-time error occurs.

For every checked exception type listed in the throws clause of m2, that same exception class or one of its supertypes must occur in the erasure (§4.6) of the throws clause of m1; otherwise, a compile-time error occurs.

If the unerased throws clause of m1 does not contain a supertype of each exception type in the throws clause of m2 (adapted, if necessary, to the type parameters of m1), a compile-time unchecked warning occurs.

s7vr
  • 73,656
  • 11
  • 106
  • 127