Some background, then some questions.
I have only recently discovered that an interface (or class) may be generic in the type of (checked) exception that its methods may throw. For example:
interface GenericRunnable<X extends Exception> {
void run() throws X;
}
The point is if you later instantiate this with, say, IOException
and invoke the run
method, the compiler knows you need to either catch IOException
or mark it as thrown. Better still, if X
was a RuntimeException
, you don't need to handle it at all.
Here's a contrived example using the above interface, but it's basically a callback and should be quite common.
public <X extends Exception> void runTwice(GenericRunnable<X> runnable) throws X {
runnable.run(); runnable.run();
}
...
public myMethod() throws MyException {
runTwice(myRunnable);
}
We're calling a generic utility method runTwice
(perhaps defined in an external library) to run our own specific method with a specific checked exception, and we don't lose any information about which specific checked exception might be thrown.
The alternative would have been to simply use throws Exception
on both the Runnable.run
method and the runTwice
method. This would not restrict any implementation of the Runnable
interface but the advantage of checked exceptions would be lost. Or there could have been no throws
at all, also losing the advantage of checked exceptions and potentially forcing the implementation to wrap.
Because I had never seen throws X
, maybe I've missed something. Furthermore, I have seen the callback example used as an argument against checked exceptions several times without it being refuted. (This question is not interested in the pros/cons of checked exceptions.)
Is throws X
generally a good idea? What are the pros and cons? Can you give some examples that either use throws X
or didn't but should have?
Basically, I would like some further insight. You might comment on the following examples.
OutputStream
throws IOException
(perhaps ByteArrayOutputStream
could extends GenericOutputStream<RuntimeException>
)
Callable
/ Future.get
Commons Pool borrowObject
/ makeObject
(Since editing, I am not asking if these could/should have been designed differently in retrospect. Rather, would throws X
be better than throws Exception
.)
A method can throw one of several exceptions. Eg: public void dosomething() throws IOException, AWTException { // .... } This signals that the method can eventually throw one of those two exceptions (and also any of the unchecked exceptions).
Using the Throws keyword Throws is a keyword used to indicate that this method could throw this type of exception. The caller has to handle the exception using a try-catch block or propagate the exception. We can throw either checked or unchecked exceptions.
The most straightforward way would be to use a try-catch block, wrap the checked exception into an unchecked exception and rethrow it: List<Integer> integers = Arrays. asList(3, 9, 7, 0, 10, 20); integers. forEach(i -> { try { writeToFile(i); } catch (IOException e) { throw new RuntimeException(e); } });
Java throws keyword We use the throws keyword in the method declaration to declare the type of exceptions that might occur within it. As you can see from the above syntax, we can use throws to declare multiple exceptions.
I use this pattern all the time, mostly for functional-style java.
Pros:
You can have several flavors of a higher-order pattern like Visitor, to wit:
interface ExceptionalVoidVisitor< E extends Exception > {
void handleA( A a ) throws E;
void handleB( B b ) throws E;
}
interface VoidVisitor extends ExceptionalVoidVisitor< RuntimeException > {}
interface ExceptionalVisitor< T, E extends Exception > {
T handleA( A a ) throws E;
T handleB( B b ) throws E;
}
interface Visitor< T > extends ExceptionalVisitor< T, RuntimeException > {}
Your client can declare a base exception class for all the exceptions he might throw and you end up with a fully general library.
Cons:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With