Consider:
try { // Some code here } catch (IOException e) { throw e; } catch (Exception e) { throw e; }
What is the difference between throw e
and throw new Exception(e)
?
try { // Some code here } catch (IOException e) { throw new IOException(e); } catch (Exception e) { throw new Exception(e); }
Catch and Catch (Exception e) have the same output, and the result is also the same if I write Throw or Throw e. @MarcGravell - Marc yes if he throws e there is a difference.
While when you say throw new Exception() this means you are saying move the program control to caller and don't execute the further statements after this throw statement.
The throws keyword is used to declare which exceptions can be thrown from a method, while the throw keyword is used to explicitly throw an exception within a method or block of code. The throws keyword is used in a method signature and declares which exceptions can be thrown from a method.
"throw "and "throw new" Exception() In the above case, throws the original exception but resets the stack trace , destroying all stack trace information until your catch block. This means that, it excludes stack information from the point where you called "Throw ex" .
If you don't need to adjust the exception type, you rethrow (throw further) the same instance without any changes:
catch (IOException e) { throw e; }
If you do need to adjust the exception type, you wrap e
(as a cause) into a new exception of the type required.
catch (IOException e) { throw new IllegalArgumentException(e); }
I consider all other scenarios a code smell. Your second snippet is a good example of it.
Here are answers to the questions that might pop up.
Why would I want to rethrow an exception?
You can let it go. But if it happens, you won't be able to do anything at this level.
When we catch an exception in a method, we are still in that method and have access to its scope (e.g. local variables and their state). Before we rethrow the exception, we can do whatever we need to (e.g. log a message, send it somewhere, make a snapshot of the current state).
Why would I want to adjust an exception?
As a rule of thumb,
Higher layers should catch lower-level exceptions and, in their place, throw exceptions that can be explained in terms of the higher-level abstraction.
Effective Java - 2nd Edition - Item 61: Throw exceptions appropriate to the abstraction
In other words, at some point, an obscure IOException
should be transformed into a perspicuous MySpecificBusinessRuleException
.
I called it "adjusting the exception type", smart guys call it exception translation (exception chaining, in particular).
To make it clear, let's have some foolish examples.
class StupidExample1 { public static void main(String[] args) throws IOException { try { throw new IOException(); } catch (IOException e) { throw new IOException(new IOException(e)); } } }
results in a verbose stack trace like
Exception in thread "main" java.io.IOException: java.io.IOException: java.io.IOException at StupidExample1.main(XXX.java:XX) Caused by: java.io.IOException: java.io.IOException ... 1 more Caused by: java.io.IOException at StupidExample1.main(XXX.java:XX)
which can (and should) be effectively reduced to
Exception in thread "main" java.io.IOException at StupidExample1.main(XXX.java:XX)
Another one:
class StupidExample2 { public static void main(String[] args) { takeString(new String(new String("myString"))); } static void takeString(String s) { } }
It's obvious that new String(new String("myString"))
is a wordy version of "myString"
and should be refactored to the latter.
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