What is the exact order of execution for try, catch, and finally?

In this java code

import java.io.IOException; public class Copy { public static void main(String[] args) { if (args.length != 2) { System.err.println("usage: java Copy srcFile dstFile"); return; } int fileHandleSrc = 0; int fileHandleDst = 1; try { fileHandleSrc = open(args[0]); fileHandleDst = create(args[1]); copy(fileHandleSrc, fileHandleDst); } catch (IOException ioe) { System.err.println("I/O error: " + ioe.getMessage()); return; } finally { close(fileHandleSrc); close(fileHandleDst); } } static int open(String filename) { return 1; // Assume that filename is mapped to integer. } static int create(String filename) { return 2; // Assume that filename is mapped to integer. } static void close(int fileHandle) { System.out.println("closing file: " + fileHandle); } static void copy(int fileHandleSrc, int fileHandleDst) throws IOException { System.out.println("copying file " + fileHandleSrc + " to file " + fileHandleDst); if (Math.random() < 0.5) throw new IOException("unable to copy file"); System.out.println("After exception"); } } 

the conclusion that I expect

 copying file 1 to file 2 I/O error: unable to copy file closing file: 1 closing file: 2 

However, sometimes I get this expected result, and in other cases I get the following output:

 copying file 1 to file 2 closing file: 1 closing file: 2 I/O error: unable to copy file 

and sometimes even this conclusion:

 I/O error: unable to copy file copying file 1 to file 2 closing file: 1 closing file: 2 

and I get the first, second or third output, it seems to happen by chance during each performance. I found THIS POST , which seems to be talking about the same problem, but I still don’t understand why I sometimes get output 1, 2 or 3. If I understand this code correctly then output 1 should be the one what i get every time (exception occurs). How can I guarantee that I will get pin 1 in sequence or can I say when I get output 1 or when I get output 2 or 3?

+7
java exception
source share
5 answers

The problem is that you are writing some output to System.out , and some to System.err . These are independent streams with independent buffering. The time at which they were reset, to my knowledge, is not indicated.

Not to mention that when writing to different streams, you cannot use the order in which the output is displayed to determine the order in which println() calls occurred. Note that the output in System.out always displayed in the expected order.

Regarding the order of execution, the try body is executed first. If it throws an exception, then the body of the corresponding catch clause is executed. The finally block is always executed last.

+17
source share

Run the Try block first if it succeeds, if Try refuses the block, and then catch executes and finally executes. What will happen, finally, the block will be executed.

But

If you call System.exit(0) , finally the block fails

+3
source share

The thing with exception handling using the catch try block is that the control will go inside try if it gets any exception inside the catch block. But control will go to the final block every time it performs.

+2
source share

You are writing your error message for both stdout and stderr. They have different buffers, so there is no guarantee that the output you see will be in the order in which you created it between the two output streams.

Since I see no errors in your code (although an extra return; in your catch segment is stuck in my craw a bit), let me suggest you write all your messages in stderr and see, the message order is a little more expected.

+1
source share

You have one glitch in your example that I would remove. You write both System.out and System.err and check the console to correctly synchronize both threads. To remove side effects, I would just use one thread here.

+1
source share

All Articles