6

Consider the following interface:

package hf;

public interface BadInterface 
{
    void meth() throws Exception;
}

Which is implemented by the following class:

package hf;

public class apples implements BadInterface
{
    public static void main(String[] args)
    {
        new apples().meth();
    }

    public void meth()
    {
        System.out.println("Ding dong meth.");
    }
}

Although meth() is a method that throws an exception, the caller of the method meth() is not having to handle or declare the exception and yet the program runs successfully. Why is this the case? Does it not violate the rule that whenever you call a method that throws an exception, you need to catch the exception or declare that you throw the exception yourself?

user3760100
  • 679
  • 1
  • 9
  • 20

2 Answers2

8

When you implement an interface method, you are allowed to declare that you throw fewer exceptions than listed in the interface.

When you call new apples().meth(), you are invoking meth() on an apples instance. The compiler knows this doesn't throw anything, so you are fine.

Had you done:

BadInterface foo = new apples();  // Note: should be Apples (code style)
foo.meth();

then you would need to catch the exception declared in the interface, because the compiler only knows it's dealing with a BadInterface instance.

Duncan Jones
  • 67,400
  • 29
  • 193
  • 254
  • Also note that Exceptions aren't part of a method's signature. That's why you could implement the method without having to add `throws Exception` to it. You can also add Exceptions: `public void meth() throws IOException, FooException` – Davio Dec 19 '14 at 12:01
  • 1
    @Davio Exceptions are certainly relevant in a signature - you can't throw any checked exceptions that aren't listed in the interface, for example. – Duncan Jones Dec 19 '14 at 12:03
  • 1
    The recent, more fitting term is "shape", relevant to lambda conversions. Declared exceptions definitely contribute to the method shape. – Marko Topolnik Dec 19 '14 at 12:07
  • @Duncan you can actually, but only if the Exception is a subclass of the one thrown in the interface. – Davio Dec 19 '14 at 12:09
  • @Davio Perhaps we are talking about different things. You can certainly throw a subclass of an allowed exception. So in the unlikely case that the interfaces has `throws Exception`, then sure - you can add anything. Was that what you were suggesting? – Duncan Jones Dec 19 '14 at 12:11
  • That was what I was thinking about. :) I was also confused with the return type, which isn't part of the signature. The Exception list is with the subclassing options. – Davio Dec 19 '14 at 12:11
0

According to JLS Requirements in Overriding and Hiding:

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:

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.

Means that extending method can have only a stronger exception policy. If it has a weaker restrictions, than such method can't be used instead of a base method and it breaks concept of overriding.

Community
  • 1
  • 1
Mikhail
  • 4,175
  • 15
  • 31