How can I throw an excluded exception in a try block?

From Java 7, we can use the try-with-resources statement:

static String readFirstLineFromFile(String path) throws IOException { try (BufferedReader br = new BufferedReader(new FileReader(path))) { return br.readLine(); } } 

if br.readLine() and br.close() both throw an exception , readFirstLineFromFile will throw an exception from the try block (an exception from br.readLine() ), and an exception will be thrown from the implicit finally block of the try-with-resources statement ( br.close() exception br.close() ) will be suppressed.

In this case, we can get suppressed exceptions from the implicit finally block by calling the getSuppresed method from the exception, try the block as follows:

 try { readFirstLineFromFile("Some path here..."); // this is the method using try-with-resources statement } catch (IOException e) { // this is the exception from the try block Throwable[] suppressed = e.getSuppressed(); for (Throwable t : suppressed) { // Check t type and decide on action to be taken } } 

But suppose we need to work with a method written in an older version than Java 7, which uses the finally block:

 static String readFirstLineFromFileWithFinallyBlock(String path) throws IOException { BufferedReader br = new BufferedReader(new FileReader(path)); try { return br.readLine(); } finally { if (br != null) br.close(); } } 

then if br.readLine() and br.close() again both throw an exception , the situation will be canceled. The readFirstLineFromFileWithFinallyBlock method will throw an exception from the finally block ( br.close() exception), and an exception from the try block ( br.readLine() exception) will be suppressed.

So my question is: how can we extract the excluded exceptions from the try block in the second case?

Source: http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

+6
source share
2 answers

You cannot, in principle. The thrown exception is lost if br.close() throws.

Closest you could have a catch that assigns a value to the locla variable:

 static String readFirstLineFromFileWithFinallyBlock(String path) throws IOException { IOException exception = null; BufferedReader br = new BufferedReader(new FileReader(path)); try { return br.readLine(); } catch (IOException e) { exception = e; } finally { try { if (br != null) br.close(); } catch (IOException e) { // Both the original call and close failed. Eek! // Decide what you want to do here... } // close succeeded, but we already had an exception if (exception != null) { throw exception; } } } 

... but it only handles an IOException (and not any unchecked exceptions) and is terribly messy.

+6
source

an exception from the try block (br.readLine () exception) will be suppressed.

This is not entirely correct. The Java language specification writes :

  • If the execution of the try block terminates abruptly due to the throwing of the value of V, then there is a choice:

    • If the run-time type of V is not an assignment compatible with the subtle exception class of any catch clause from the try statement, then the finally block is executed. Then there is a choice:

      • If the finally block completes normally, then the try statement terminates abruptly due to the throwing of the value V.

      • If the finally block completes abruptly for mind S, then the try statement terminates abruptly for reason S (and the outlier of V is discarded and forgotten).

That is, the exception is "discarded and forgotten," and not just suppressed.

BTW, since the mechanism for attaching an excluded exception to another exception was introduced in Java 7, there was no general support for this in Java 6. Therefore, code targeting in Java 6 cannot be used.

+1
source

Source: https://habr.com/ru/post/944708/


All Articles