3

I am working on a project (someone else's code) in which a method was declared to throw a bunch of checked exceptions it could not possibly throw.

Basically, the method looked like this:

// Assume E1 extends Exception
// Assume E2 extends Exception
// Assume E3 extends Exception
public void method(Object param) throws E1, E2, E3 {
    // Call a bunch of methods, none of which are declared to
    // throw checked exceptions.
}

Of course, I deleted the throws clause. And of course, I received no compiler errors from doing so because throwing those exceptions is impossible based on a static analysis of the code.

So my question is why Eclipse and its builder, or javac, wasn't warning me about these spurious throws declarations? Is there something I can turn on to make this happen?

The worst is that if I was getting the warnings I ought to be getting, there would be a cascading effect because all callers of method() either re-declare the same throws or contain a bunch of useless try/catch blocks which absolutely confuse the meaning of the program.

0xbe5077ed
  • 4,565
  • 6
  • 35
  • 77

3 Answers3

2

You can force the Eclipse to give compile time error/warning if the throws clause contains unnecessary exceptions in it.

Please refer to the following screenshot:

enter image description here

rizzz86
  • 3,862
  • 8
  • 35
  • 52
1

This can actually break downstream users, unfortunately, and it might be prohibitively expensive for Eclipse to find them all.

Part of the issue is that

try {
  cantThrowFooException();
} catch (FooException e) {
  // whatever
}

will not compile if javac is sure that a FooException cannot be thrown. So removing FooException from the throws clause of a method can enable the compiler to prove that FooException isn't thrown in a try block downstream, and the result will be a failed compile.

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
  • Why is that a problem? – 0xbe5077ed Jun 08 '15 at 21:17
  • 2
    Because it means that when you remove a `throws` clause, it can cause any other class that calls that method to stop compiling completely. It means Eclipse would have to search every other class that references this class to be sure you're not breaking the compile, and if you're working on a library other people use, you could break them without knowing about it. – Louis Wasserman Jun 08 '15 at 21:19
  • Indeed, but how is that different than,say, removing a parameter, or, for that matter, **adding** a checked exception? I'm not interested in interface design best practices, I'm interested in program correctness, and why Java ***forces*** you to declare a checked exception if you provably throw it, but is OK with you lying about it if you provably don't. – 0xbe5077ed Jun 08 '15 at 21:29
1

Because method is not final and I assume it is part of a class that is not final. Thus it can be overridden by another method that throws those exceptions.

If you changed your question so that either method or its class was final you would have another interesting question.

emory
  • 10,725
  • 2
  • 30
  • 58