问题
As i understand it, Java 7's suppressing exceptions feature is an automatic one. In other words, exceptions happening in what used to be a finally block in 6 are automatically suppressed in favor of exception that took place upon resource allocation.
So, in this example things may go wrong with a) opening a resource and b) closing a resource or c) possibly both.
As i understand it, Java 7 will throw exception that took place upon opening, whom we can ask to give us suppressed exceptions, which took place elsewhere.
try (BufferedReader inputReader = Files
.newBufferedReader(Paths.get(new URI(
"file:///Users/me/Desktop/readme.txt")), Charset
.defaultCharset())) {
String inputLine;
while ((inputLine = inputReader.readLine()) != null) {
System.out.println(inputLine);
}
}
The question is .. Can programmer decide what gets suppressed? After all, public addSuppressed()
is there.
Please provide an example and use case.
回答1:
This is not arbitrary—the suppressed exceptions are the ones that would otherwise mask the main exception that caused the try
block to fail—and that's the ones in the finally
block. This feature ensures that you get all the exceptions thrown in the whole construct, but the one you catch will be the more important one.
You don't get to choose what gets suppressed. The method is there, for sure, otherwise the whole thing wouldn't work. If you like, you can write your own exception handling code and use addSuppressed
ad libitum.
回答2:
Why new reply:
- more clarifications (at least I needed them once reading, especially on the
catch
side) - added code
- added use-case / example for
addSuppressed
usage (catch
)
Case-by-case:
- old
try
-catch
-finally
(ortry
-finally
) will suppress exceptions from all butfinally
block. Also, nothing will be in suppressed exceptions list, if you touch it, regardless of whether something was suppressed or not. try
-with-resources-finally
will propagatetry
exception, withfinally
one being in suppressed list.try
-...-catch
-finally
works similarly. Ifcatch
throws, it suppressestry
exception making it lost, unless you useaddSupressed()
on catch exception manually (tying original exception to new one being thrown). I believe this to be the case accepted answer covers in last paragraph.
public class WhichIsSupressedTryCatchOrFinally {
public static void main(String[] args) {
try {
// tryOrFinally(); // throws finally, try one is lost
// tryCatchOrFinally(); // as above, no suppression info
// tryWithResourcesOrFinally(); // throws try, adds finally one to it though automatically
tryWithResourcesCatchOrFinallyCatchThrows();
tryWithResourcesCatchOrFinallyByHand(); // throws catch, but adding "by hand" try, adds finally also
} catch (Exception e) {
e.printStackTrace();
// System.out.println(Arrays.toString(e.getSuppressed())); -> not needed!
}
}
static class AResource implements AutoCloseable {
@Override
public void close() throws NumberFormatException {
throw new NumberFormatException("did not see that one coming, did'ya?");
}
}
private static void tryWithResourcesOrFinally() throws FileNotFoundException {
try (AResource a = new AResource()) {
throw new FileNotFoundException("try");
}
}
private static void tryWithResourcesCatchOrFinallyCatchThrows() throws Exception {
try (AResource a = new AResource()){
throw new IOException("try");
} catch (Exception e) {
throw new NoSuchElementException("catch");
}
}
private static void tryWithResourcesCatchOrFinallyByHand() throws Exception {
try (AResource a = new AResource()){
throw new IOException("try");
} catch (Exception e) {
NoSuchElementException aCatch = new NoSuchElementException("catch");
aCatch.addSuppressed(e);
throw aCatch;
}
}
private static void tryOrFinally() throws Exception {
try {
throw new IOException("try");
} finally {
throw new Exception("finally");
}
}
private static void tryCatchOrFinally() throws Exception {
try {
throw new IOException("try");
} catch (Exception e) {
throw new NoSuchElementException("catch");
} finally {
throw new Exception("finally");
}
}
}
So, you don't choose what gets suppressed, and addSuppressed
is to make stack traces more complete.
Outputs:
try - catch - finally, catch throws interrupting execution:
try - catch - finally, all throws, catch throwable gets added try exception, which already has finally one bundled in
来源:https://stackoverflow.com/questions/11603300/who-decides-what-exceptions-get-suppressed