There is no difference in behavior between the two code samples. (In particular, stacktraces are written when an exception is thrown, and not when it is thrown, so the restored exception will still have the original stack trace). Usually people use a simpler idiom.
This does not mean that re-construction does not have its goals. For example, if you want to handle all exceptions except FooBarExceptions, you can write:
try { // bad code } catch (FooBarException e) { throw e; } catch (Exception e) { e.printStackTrace(); }
Or if the decision to handle the exception is more active than just checking its type, you can simply catch it and reconstruct it if it turns out that you cannot handle it:
for (int attempts = 0; attemps < 6; attempts++) { try { return crankyMethod(); } catch (Exception e) { if (fatal(e)) { throw e; } else { // try again continue; } } }
It is worth noting that when people talk about retreating, some of them want to throw another exception, as in the following example:
for (int i = 0; i < array.length; i++) { try { process(array[i]); } catch (Exception e) { throw new RuntimeException("Could not process element at index " + i, e); } }
The advantage of this pattern is to decorate the original exception with additional information that may be relevant (in the example above: what data cannot be processed). Note that the original exception is passed to the constructor of the new one, so its stack trace is not lost.
source share