3

I have just realized that I can write a method declaring the same checked exception several times.

public void myMethod() throws MyException, MyException, MyException {

I can't think of a reason why I would want to do this. I have been searching for a while but I am not being able to find if there is a resource that explains why is this acceptable or how could it be good. Can anyone point me to some resource about this?

Jeffrey Bosboom
  • 13,313
  • 16
  • 79
  • 92
  • What do you think `throws` means? – JB Nizet Feb 03 '15 at 20:30
  • 1
    Syntax sometimes allows many non-logical things, question is why would you write such a thing? – m0skit0 Feb 03 '15 at 20:30
  • You can only throw one exception from a method because doing so transfers control away from the method. i.e. no more code from the method is executed when an exception is thrown. – DennisW Feb 03 '15 at 20:31
  • 3
    I think it's all about syntax, it will work as if you wrote `throws MyException`. Restricting that, would be a superfluous check by the compiler. – Christian Tapia Feb 03 '15 at 20:32
  • 2
    I can't think of a reason why I would declare a variable `int useless = 0;` and never use it, but Java lets me. Maybe you'd want to write it that way to increase readability. – DaaaahWhoosh Feb 03 '15 at 20:33
  • 1
    It's a type definition. Why would the compiler care if you declare it multiple times? How many other places in the java lingo is declaring a particular type multiple times a problem? I would expect a problem only where a variable name is concerned – kolossus Feb 03 '15 at 20:33
  • That is only a redundant declaration of one exception type that could be thrown by a method. – Gren Feb 03 '15 at 21:00

2 Answers2

4

There is nothing in the JLS that prevents you from specifying the same exception type (or even subtypes) in the throws clause. The only restriction, according to the JLS, Section 8.4.6, is:

It is a compile-time error if an ExceptionType mentioned in a throws clause is not a subtype (§4.10) of Throwable.

So, this compiles:

throws RedundantException, RedundantException, RedundantException

My IDE warns me of "duplicate throws", but it's not a compiler error.

I see no good reason ever to do this. It has never occurred to me even to attempt this.

This compiles, even if MySubclassException subclasses MyException:

throws MyException, MySubclassException, MyException, MySubclassException

The only reason I can think of to list subclass exception types in the throws clause is to document in your own Javadocs that the subclass may be thrown, so it can be handled separately.

@throws MyException If something general went wrong.
@throws MySubclassException If something specific went wrong.

Even so, my IDE warns me of "a more general exception" in the list.

Incidentally, it doesn't seem to matter whether any of the exception types in the examples above are checked.

rgettman
  • 176,041
  • 30
  • 275
  • 357
  • A practical example: some methods in java.nio throw IOException and also an "optional specific exception" like FileAlreadyExistsException (a subtype of IOException). – Jeffrey Bosboom Feb 03 '15 at 21:55
1

As mentioned in rgettman's answer, there's no semantic meaning to the duplicate throws declarations. However, javac still records them in the compiled class file, making them available to reflection, as can be seen in the following example:

public class Main {
    public static void main(String[] args) throws IOException, IOException,
            IOException, NoSuchMethodException {
        Arrays.stream(Main.class.getMethod("main", String[].class).getExceptionTypes())
                .forEachOrdered(System.out::println);
    }
}

which prints

class java.io.IOException
class java.io.IOException
class java.io.IOException
class java.lang.NoSuchMethodException

This isn't useful (and probably exposes buggy consumers of Method.getExceptionTypes()), but it is a behavioral difference caused by the duplicate throws declarations.

Jeffrey Bosboom
  • 13,313
  • 16
  • 79
  • 92