Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

java

exception

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 output that I expect is

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 output and at other times 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 output:

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

and whether I get the first, second or third output seems to happen randomly during every execution. I found THIS POST that apparently talks 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 what I get every time (the exception occurs). How do I ensure that I get output 1 consistently, or be able to tell when I will be getting output 1 or when I will be getting output 2 or 3?

like image 225
user13267 Avatar asked Jul 26 '13 06:07

user13267


5 Answers

The issue is that you are writing some output to System.out and some to System.err. These are independent streams, with independent buffering. The timing of when they are flushed is, as far as I know, not specified.

The short of it is that when writing to different streams, you cannot use the order in which the output shows up to determine the order in which the calls to println() occurred. Note that the output to System.out always appears in the expected order.

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

like image 173
Ted Hopp Avatar answered Nov 20 '22 04:11

Ted Hopp


First execute Try block if it is success finally will execute, if try block fail then catch will execute and finally execute. What ever happen finally block will execute.

But

If you call System.exit(0) finally block not executed

like image 27
Ruchira Gayan Ranaweera Avatar answered Nov 20 '22 05:11

Ruchira Gayan Ranaweera


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

like image 40
Maclane Avatar answered Nov 20 '22 04:11

Maclane


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

Since I can see no errors in your code (although the superfluous return; in your catch segment stuck in my craw a little bit), let me suggest that you write all of your messages to stderr, and see if the message order is a little more in line with what you were expecting.

like image 37
Curt Avatar answered Nov 20 '22 04:11

Curt


You have one glitch in your example which I would remove. You are writing to both System.out and System.err and expection your console to synchronize both streams correctly. To remove side effects I would just use one stream here.

like image 1
Matthias Avatar answered Nov 20 '22 04:11

Matthias