Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should java try blocks be scoped as tightly as possible?

I've been told that there is some overhead in using the Java try-catch mechanism. So, while it is necessary to put methods that throw checked exception within a try block to handle the possible exception, it is good practice performance-wise to limit the size of the try block to contain only those operations that could throw exceptions.

I'm not so sure that this is a sensible conclusion.

Consider the two implementations below of a function that processes a specified text file.

Even if it is true that the first one incurs some unnecessary overhead, I find it much easier to follow. It is less clear where exactly the exceptions come from just from looking at statements, but the comments clearly show which statements are responsible.

The second one is much longer and complicated than the first. In particular, the nice line-reading idiom of the first has to be mangled to fit the readLine call into a try block.

What is the best practice for handling exceptions in a funcion where multiple exceptions could be thrown in its definition?

This one contains all the processing code within the try block:

void processFile(File f) {   try   {     // construction of FileReader can throw FileNotFoundException     BufferedReader in = new BufferedReader(new FileReader(f));      // call of readLine can throw IOException     String line;     while ((line = in.readLine()) != null)     {       process(line);     }   }   catch (FileNotFoundException ex)   {     handle(ex);   }   catch (IOException ex)   {     handle(ex);   } } 

This one contains only the methods that throw exceptions within try blocks:

void processFile(File f) {   FileReader reader;   try   {     reader = new FileReader(f);   }   catch (FileNotFoundException ex)   {     handle(ex);     return;   }    BufferedReader in = new BufferedReader(reader);    String line;   while (true)   {     try     {       line = in.readLine();     }     catch (IOException ex)     {       handle(ex);       break;     }      if (line == null)     {       break;     }      process(line);   } } 
like image 643
Iain Samuel McLean Elder Avatar asked Apr 13 '10 23:04

Iain Samuel McLean Elder


People also ask

Do try-catch blocks have scope?

Try-Catch and Variable Scope -it is not available to the scope outside. We would have the same problem if we tried to return the price inside of the catch block. Here's a key point: Variables declared inside a try or catch block are local to the scope of the block.

Which is the correct try block handling?

The try block contains set of statements where an exception can occur. A try block is always followed by a catch block, which handles the exception that occurs in associated try block. A try block must be followed by catch blocks or finally block or both.

Are try-catch blocks good practice?

So using few try-catch blocks shouldn't affect a performance at all. In some opinion writing code that way obfuscates the code and does not even recall "clean code", in others opinion it's better to use try only for lines which can actually throw any exception. It's up to you decide (or the team convention).

Why should I not wrap every block in try-catch?

Exponentially because if each method branches in two different ways then every time you call another method you're squaring the previous number of potential outcomes. By the time you've called five methods you are up to 256 possible outcomes at a minimum.


1 Answers

The basic premise here is false: the size of a try block makes no difference in performance. Performance is affected by actually raising exceptions at runtime, and that's independent of the size of the try block.

However, keeping try blocks small can lead to better programs.

You might catch exceptions to recover and proceed, or you might catch them simply to report them to the caller (or to a human, via some UI).

In the first case, failures from which you can recover are often very specific, and this leads to smaller try blocks.

In the second case, where an exception is caught so that it can be wrapped by another exception and re-thrown, or displayed to the user, small try blocks mean that you know more precisely which operation failed, and the higher-level context in which that call was made. This allows you to create more specific error reports.

Of course, there are… exceptions (sorry!) to these guidelines. For example, in some cases very specific error reports could be a security problem.


It might be useful to know what effect a try block has on the compiled code. It doesn't change the compiled instructions at all! (Of course, the corresponding catch block does, since it's like any other code.)

A try block creates an entry in the exception table associated with the method. This table has a range of source instructions counters, an exception type, and a destination instruction. When an exception is raised, this table is examined to see if there is an entry with a matching type, and a range that includes the instruction that raised the exception. If it does, execution branches to the corresponding destination number.

The important thing to realize is that this table isn't consulted (and has no effect on running performance) unless it's needed. (Neglecting a little overhead in the loading of the class.)

like image 67
erickson Avatar answered Oct 06 '22 14:10

erickson