2

The SwingWorker method doInBackground is abstract and the documentation says it throws an Exception but a concrete implementation does not seem to need to declare that it throws Exception. Eclipse doesn't complain so it seems that Exception itself is not a "checked" exception. Of course any code can throw a RuntimeException (which is an Exception) so this documentation seems to be saying something redundant.

protected abstract T doInBackground()
                             throws Exception

A concrete example:

public Boolean doInBackground() // concrete for abstract
{
        performLongRunningProcedure();
        return true;
}

I can speculate that it might be that the lack of a warning is a limitation in the IDE and/or language but it seems there might be a practical purpose to the throws Exception clause. Why would any method, concrete or abstract, ever declare "throws Exception"?

user3378165
  • 6,546
  • 17
  • 62
  • 101
H2ONaCl
  • 10,644
  • 14
  • 70
  • 114
  • Check this post: http://stackoverflow.com/questions/5875414/why-cant-overriding-methods-throw-exceptions-broader-than-the-overriden-method – Beri Jun 14 '16 at 20:17
  • It looks relevant. My takeaway is that the abstract method says what we are ALLOWED TO declare can be thrown and the concrete method can declare anything narrower or as in my example, nothing at all. By being broad, the abstract method imposes the least limitations. – H2ONaCl Jun 14 '16 at 20:46
  • This question is already answered http://stackoverflow.com/questions/2008424/why-do-you-have-to-write-throws-exception-in-a-class-definition – Vikash Lal Dodani Jun 14 '16 at 21:10
  • Vikash Dodani, That looks inferior to the link form Beri. Check it out and you'll understand. – H2ONaCl Jun 14 '16 at 22:38

2 Answers2

3

The link Beri provides explains the technical rules behind declaring exceptions thrown across methods. To answer your question of "why throws Exception":

In a concrete (might put "final" in here, but I won't) method one should almost never need to declare "throws Exception", because a concrete method will know exactly which exceptions it could possibly throw and should list those explicitly.

An abstract method/interface method is different. You have three choices:

  1. Don't declare any thrown exceptions. This means that the only exceptions that may be thrown by any implementation are RuntimeException. This implies no checked exceptions can be thrown and that it should, in almost all cases, be safe to call this method without expecting failure. If it does throw an exception, there's nothing you can do about it.
  2. Throw specific checked exceptions. This can be done, but it's going to be a rare few cases where an abstract method can correctly predict the exact limited set of checked exceptions that could be thrown. When writing a framework with plugins, this would be a way to specify checked exceptions the framework understands how to handle (e.g. IOException in stream classes, FileNotFound). The implication of doing so is that the defined set are the only checked exceptions that could ever occur or would make sense to occur.
  3. Throw Exception. In this case it's saying that a concrete implementation will be allowed to throw any checked exceptions that make sense for that implementation, with no restrictions. An implementation might choose to throw less (or none), but is allowed to throw any checked exception. It indicates that an implementation is allowed to throw any checked exception, and a caller will be required handle Exception.

It doesn't add much value. Why not? Because the value of checked exceptions is understanding the specific exceptions that could be thrown so that they can be meaningfully handled by the caller. When you are left with just "Exception", and no indication of what an implementation might throw (or, with multiple implementations, what might vary from one to another), there's no meaningful way to handle that more so than just handling Exception, which is really no more meaningful than just handling RuntimeException.

So the only real value of declaring an abstract method with "throws Exception" is to explicitly say "we require the caller to explicitly handle exceptions that may be thrown by this method, because we can't guarantee if the implementation is likely to throw them or not." So rather than hoping an implementation won't throw an exception, one must assume it does.

user1676075
  • 3,056
  • 1
  • 19
  • 26
1

The SwingWorker method doInBackground is abstract and the documentation says it throws an Exception but a concrete implementation does not seem to need to declare that it throws Exception.

The abstract method declares that sometimes it throws Exception to allow overriding methods to declare so, if they do some operation that can throw an exception without handling the exception.

I know that some people didn't understand, so here's some code that doesn't compile:

abstract class Foo {
    abstract void foo();
}

class Bar extends Foo {
    @Override
    void foo() throws InterruptedException { Thread.sleep(5000); }
}

Eclipse will reject this code, stating that Exception InterruptedException is not compatible with throws clause in Foo.foo() (so will javac but I don't know if it gives the same error message).

Eclipse doesn't complain so it seems that Exception itself is not a "checked" exception.

it seems there might be a practical purpose to the throws Exception clause

The way checked exceptions work is throroughly explained in the official Java tutorial.

Community
  • 1
  • 1
The SE I loved is dead
  • 1,517
  • 4
  • 23
  • 27