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

if the methods readLine and close both throw exceptions, then the method readFirstLineFromFileWithFinallyBlock throws the exception thrown from the finally block; the exception thrown from the try block is suppressed. Why is the behaviour as such? Why is the exception from try block supressed?

Rekha
  • 1,403
  • 3
  • 12
  • 21

6 Answers6

1

Only exceptions within the try portion will be handled. Anything outside this (including the finally section isn't covered by a try and as such, Exceptions aren't handled.

If you want to catch/suppress the exception inside the finally block, you need to wrap if (br != null) br.close(); with it's own try/catch block, like this:

...
} finally {
  try {
    if (br != null) br.close();
  } catch (Exception e) {
    // whatever handling
  }
}
...

Also, the exception from the try block is suppressed because that's the behavior of a try block - to try something and give you a chance to recover. Since you don't catch any exceptions after your try block, no code is run in response to it.

Then, whether or not any exception is thrown, the finally block is executed. If it throws an exception, and because it's not inside a try/catch block of its own, its Exception is propagated out the method, and to the calling method.

To take the example from your comment below, as of Java 7, you'll want to refer to the documentation outlined here, and focus on the second-to-last section entitled "Supressed Exceptions", which basically says that multiple exceptions can be thrown out of a try block, up to one exception per declared resource.

As far as what happens if the resource declaration itself throws an exception, I don't have JDK7 installed, so I'm not sure. Why not put the following code in a test project (exactly as it appears, with a bogus path), see what happens, and then tell us what the result it for everyone's benefit:

try (BufferedReader br = new BufferedReader(new FileReader("a totally invalid path"))) {
  return br.readLine();
}
jefflunt
  • 33,527
  • 7
  • 88
  • 126
  • try (BufferedReader br = new BufferedReader(new FileReader(path))) { return br.readLine(); } What if try with resources and br.readline throw excetion.Which will be supressed and why? – Rekha Oct 13 '11 at 18:36
  • Can you edit your first comment (or add a new one)? You're brackets/parenthesis aren't correct, and as a result, I'm not sure I follow what you're asking. – jefflunt Oct 13 '11 at 18:56
  • That comment consists of a try-with-resources statement.Can you explain what happens when both throw exceptions? – Rekha Oct 13 '11 at 19:01
  • Oh, I see. I was previously unfamiliar with the "try-with-resources" construct as I work on JDK6, and it doesn't appear to have existed until JDK7. I answered your question (mostly), and posted a reference to the official documentation on that subject. Do us a favor, if you have JDK7 installed (I don't), then try out the code example I gave at the end, and then tell us: what happens, what exceptions are thrown, and compare that to what happens when you put a valid path (to an existing file) in there. – jefflunt Oct 13 '11 at 19:41
1

Why is the behaviour as such? Why is the exception from try block supressed?

  1. Because that's the way the architecture defines it.
  2. Because decades of experience have shown that this is the best solution to the potential ambiguity.
Hot Licks
  • 47,103
  • 17
  • 93
  • 151
0

When I checked this post, Same question as below which someone has added in comment came to me. I did bit of analysis and here is my answer.

Comment: "That comment consists of a try-with-resources statement.Can you explain what happens when both throw exceptions?"

Answer: It will throw exception for try block, The exception thrown from try-with-resource statement is suppressed.

Here is one quick sample program to understand the same.

class MyResource implements AutoCloseable {
    public void close() throws SQLException {
        throw new SQLException();
    }
}

public class Try {

    public static void main(final String[] args) {
        try(MyResource mr = new MyResource ()) {

            System.out.println("Hi");
            throw new IOException();

        } 
        catch (IOException | SQLException e) {
            System.out.println("Exception raised:" + e.getClass());
            System.out.println("Exception suppressed:" + e.getSuppressed()[0]);

        }
    }
}

The output of this program:

Hi

Exception raised: class java.io.IOException

Exception suppressed: java.sql.SQLException

027
  • 1,553
  • 13
  • 23
0

because a function can throw only one exception. The later exceptiobn supresses all the previuos

Me again
  • 496
  • 2
  • 10
0

Well, what behaviour would you want? There's no concept of multiple exceptions being thrown at once - so one of the exceptions would have to "win". It would be nice if there were some consistent way of representing "multiple things have gone wrong" in the language (support beyond just wrapping one exception in another) but the boat's sailed on that one.

This is one reason why Guava has Closeables.closeQuietly, so that the original exception won't be suppressed.

EDIT: Note that in Java 7, there are slightly more options with the try-with-resources feature. See the documentation for more details; it goes into detail about this specific situation.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • try (BufferedReader br = new BufferedReader(new FileReader(path))) { return br.readLine(); } What if try with resources and br.readline throw excetion.Which will be supressed and why? – Rekha Oct 13 '11 at 18:38
  • @Rekha: See http://download.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html - there's a lot about this. – Jon Skeet Oct 13 '11 at 18:43
0

It can only throw one exception, and the one from the "finally" block wins, according to the spec.

Finally blocks should always be coded very defensively for this reason. See:

Is a finally block without a catch block a java anti-pattern?

Community
  • 1
  • 1
Ed Staub
  • 15,480
  • 3
  • 61
  • 91