Java catch throw exception finally

throws Exception in finally blocks

The check for null is redundant. If the resource was null, then the calling method is broken should be fixed. Also, if the resource is null, that should probably be logged. Otherwise it results in a potential exception being silently ignored.

The check for null is not always redundant. Think of «resource = new FileInputStream(«file.txt»)» as the first line of the try. Also, this question was not about aspect oriented programing which many people do not use. However, the concept that the Exception should not be just ignored was most compactly handled by showing a log statement.

I typically use one of the closeQuietly methods in org.apache.commons.io.IOUtils :

public static void closeQuietly(OutputStream output) < try < if (output != null) < output.close(); >> catch (IOException ioe) < // ignore >> 

You can make this method more general with Closeable public static void closeQuietly(Closeable closeable)

If you’re using Java 7, and resource implements AutoClosable , you can do this (using InputStream as an example):

try (InputStream resource = getInputStream()) < // Use the resource. >catch( Exception ex ) < // Problem with the resource. >

Arguably a bit over the top, but maybe useful if you’re letting exceptions bubble up and you can’t log anything from within your method (e.g. because it’s a library and you’d rather let the calling code handle exceptions and logging):

Resource resource = null; boolean isSuccess = false; try < resource = Resource.create(); resource.use(); // Following line will only run if nothing above threw an exception. isSuccess = true; >finally < if (resource != null) < if (isSuccess) < // let close throw the exception so it isn't swallowed. resource.close(); >else < try < resource.close(); >catch (ResourceException ignore) < // Just swallow this one because you don't want it // to replace the one that came first (thrown above). >> > > 

UPDATE: I looked into this a bit more and found a great blog post from someone who has clearly thought about this more than me: http://illegalargumentexception.blogspot.com/2008/10/java-how-not-to-make-mess-of-stream.html He goes one step further and combines the two exceptions into one, which I could see being useful in some cases.

Читайте также:  Нажатие на экран javascript

As of Java 7 you no longer need to explicitly close resources in a finally block instead you can use try-with-resources syntax. The try-with-resources statement is a try statement that declares one or more resources. A resource is an object that must be closed after the program is finished with it. The try-with-resources statement ensures that each resource is closed at the end of the statement. Any object that implements java.lang.AutoCloseable, which includes all objects which implement java.io.Closeable, can be used as a resource.

Assume the following code:

try( Connection con = null; Statement stmt = con.createStatement(); Result rs= stmt.executeQuery(QUERY);)

If any exception happens the close method will be called on each of these three resources in opposite order in which they were created. It means the close method would be called first for ResultSetm then the Statement and at the end for the Connection object.

It’s also important to know that any exceptions that occur when the close methods is automatically called are suppressed. These suppressed exceptions can be retrieved by getsuppressed() method defined in the Throwable class.

It seems incomplete that this answer doesn’t mention the difference in behavior between this approach and how the OP’s posted example code works.

using try-with-resources throws an exception on close if the part in the try block completes normally but the close method doesn’t, unlike what the OP code does. recommending it as a replacement without acknowledging the change in behavior seems potentially misleading.

try the case i described. try block completes normally, close throws something. and reread the page you posted the link to, suppression only applies when the try block throws something.

Ignoring exceptions which occur in a ‘finally’ block is generally a bad idea unless one knows what those exceptions will be and what conditions they will represent. In the normal try/finally usage pattern, the try block places things into a state the outside code won’t be expecting, and the finally block restores those things’ state to what the outside code expects. Outside code which catches an exception will generally expect that, despite the exception, everything has been restored to a normal state. For example, suppose some code starts a transaction and then tries to add two records; the «finally» block performs a «rollback if not committed» operation. A caller might be prepared for an exception to occur during the execution of the second «add» operation, and may expect that if it catches such an exception, the database will be in the state it was before either operation was attempted. If, however, a second exception occurs during the rollback, bad things could happen if the caller makes any assumptions about the database state. The rollback failure represents a major crisis—one which should not be caught by code expecting a mere «Failed to add record» exception.

My personal inclination would be to have a finally method catch exceptions that occur and wrap them in a «CleanupFailedException», recognizing that such failure represents a major problem and such an exception should not be caught lightly.

One solution, if the two Exceptions are two different classes

try < . >catch(package1.Exception err) < . >catch(package2.Exception err) < . >finally

But sometimes you cannot avoid this second try-catch. e.g. for closing a stream

InputStream in=null; try < in= new FileInputStream("File.txt"); (..)// do something that might throw an exception during the analysis of the file, e.g. a SQL error >catch(SQLException err) < //handle exception >finally < //at the end, we close the file if(in!=null) try < in.close();>catch(IOException err) < /* ignore */ >> 

Источник

Exception thrown in catch and finally clause

I was asked to give its output. I answered 13Exception in thread main MyExc2 , but the correct answer is 132Exception in thread main MyExc1 . Why is it that? I just can’t understand where does MyExc2 go.

12 Answers 12

Based on reading your answer and seeing how you likely came up with it, I believe you think an «exception-in-progress» has «precedence». Keep in mind:

When an new exception is thrown in a catch block or finally block that will propagate out of that block, then the current exception will be aborted (and forgotten) as the new exception is propagated outward. The new exception starts unwinding up the stack just like any other exception, aborting out of the current block (the catch or finally block) and subject to any applicable catch or finally blocks along the way.

Note that applicable catch or finally blocks includes:

When a new exception is thrown in a catch block, the new exception is still subject to that catch’s finally block, if any.

Now retrace the execution remembering that, whenever you hit throw , you should abort tracing the current exception and start tracing the new exception.

«Based on reading your answer and seeing how you likely came up with it, I believe you think an «exception-in-progress» has «precedence»» Thank you. that was exactly my thought 🙂

Exceptions in the finally block supersede exceptions in the catch block.

  • If the finally block completes normally, then the try statement completes abruptly for reason R.
  • If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and reason R is discarded).

This is what Wikipedia says about finally clause:

More common is a related clause (finally, or ensure) that is executed whether an exception occurred or not, typically to release resources acquired within the body of the exception-handling block.

Let’s dissect your program.

So, 1 will be output into the screen, then q() is called. In q() , an exception is thrown. The exception is then caught by Exception y but it does nothing. A finally clause is then executed (it has to), so, 3 will be printed to screen. Because (in method q() there’s an exception thrown in the finally clause, also q() method passes the exception to the parent stack (by the throws Exception in the method declaration) new Exception() will be thrown and caught by catch ( Exception i ) , MyExc2 exception will be thrown (for now add it to the exception stack), but a finally in the main block will be executed first.

catch ( Exception i ) < throw( new MyExc2() ); >finally

A finally clause is called. (remember, we’ve just caught Exception i and thrown MyExc2 ) in essence, 2 is printed on screen. and after the 2 is printed on screen, a MyExc1 exception is thrown. MyExc1 is handled by the public static void main(. ) method.

«132Exception in thread main MyExc1»

In essence, if you have a finally in a try/catch clause, a finally will be executed (after catching the exception before throwing the caught exception out)

«In q(), an exception is thrown but before the exception is fully thrown, a finally clause is first executed, so, 3 will be printed to screen. » Er. no, the first exception thrown in q passes execution to the empty catch block in q (which swallows this exception), then to the finally block in q . Said finally block prints 3 , then throws a new exception, which thanks to q ‘s throws Exception is passed up the stack to the parent.

Finally clause is executed even when exception is thrown from anywhere in try/catch block.

Because it’s the last to be executed in the main and it throws an exception, that’s the exception that the callers see.

Hence the importance of making sure that the finally clause does not throw anything, because it can swallow exceptions from the try block.

A method can’t throw two exceptions at the same time. It will always throw the last thrown exception , which in this case it will be always the one from the finally block.

When the first exception from method q() is thrown, it will catch’ed and then swallowed by the finally block thrown exception.

q() -> thrown new Exception -> main catch Exception -> throw new Exception -> finally throw a new exception (and the one from the catch is «lost»)

class MyExc1 extends Exception <> class MyExc2 extends Exception <> class MyExc3 extends MyExc2 <> public class C1 < public static void main(String[] args) throws Exception < try < System.out.print("TryA L1\n"); q(); System.out.print("TryB L1\n"); >catch (Exception i) < System.out.print("Catch L1\n"); >finally < System.out.print("Finally L1\n"); throw new MyExc1(); >> static void q() throws Exception < try < System.out.print("TryA L2\n"); q2(); System.out.print("TryB L2\n"); >catch (Exception y) < System.out.print("Catch L2\n"); throw new MyExc2(); >finally < System.out.print("Finally L2\n"); throw new Exception(); >> static void q2() throws Exception < throw new MyExc1(); >> 
TryA L1 TryA L2 Catch L2 Finally L2 Catch L1 Finally L1 Exception in thread "main" MyExc1 at C1.main(C1.java:30) 

While this code snippet may be the solution, including an explanation really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion

The logic is clear till finish printing out 13 . Then the exception thrown in q() is caught by catch (Exception i) in main() and a new MyEx2() is ready to be thrown. However, before throwing the exception, the finally block have to be executed first. Then the output becomes 132 and finally asks to thrown another exception new MyEx1() .

As a method cannot throw more than one Exception , it will always throw the latest Exception . In other words, if both catch and finally blocks try to throw Exception , then the Exception in catch is swallowed and only the exception in finally will be thrown.

Thus, in this program, Exception MyEx2 is swallowed and MyEx1 is thrown. This Exception is thrown out of main() and no longer caught, thus JVM stops and the final output is 132Exception in thread main MyExc1 .

In essence, if you have a finally in a try/catch clause, a finally will be executed AFTER catching the exception, but BEFORE throwing any caught exception, and ONLY the lastest exception would be thrown in the end.

Источник

Java catch throw exception finally

правильно ли понимаю, что когда я работаю с проектом, в котором есть несколько потоков исполнения, может быть вот такая ситуация. Один из этих потоков запускается и завершается успешно, а затем выбрасывает исключение внутри блока try-catch. Оставшиеся потоки исполнения продолжают свою работу, но никакой код в блоке finally не выполняется. Тогда блок finally при обработке исключений не будет выполнен?

я читаю про исключения на 1м и в принципе понимаю, но не очень. ps: зачем только я начал с java core. pss: если вы это читаете, и я до сих пор на первом, то либо я прохожу другой курс, либо читаю книгу по джаве, параллельно проходя этот курс, либо решил взять перерыв на неопределенный срок времени. никогда не сдамся)

Есть подозрение, что так будет правильнее.

обращу внимание на некоторую неточность. цитата «Создание исключения При исполнении программы исключение генерируется JVM или вручную, с помощью оператора throw» в java исключения это тоже объекты поэтому создается исключение так же как объект new Exception. а бросается в программе с помощью оператора throw. обычно эти операции объединяют в одну throw new Exception(«aaa»);

если что я пишу это с 3 уровня. Под конец лекций я читал статью про бафридер, после нашел там ссылку на потоки вводов, а потом чтобы понять что там говориться ввел гугл про исключение и нашел эту статью, спасибо автору, это статья очень помогла. PS если ты читаешь этот комментарий и видишь что у меня нет прогресса(то есть если я все еще на 3 уровне или чуточку больше), то скажи мне, что я нуб и не дошел до 40 лвла

Источник

Оцените статью