Is this try-catch nesting preferable - any execution cost?

Well, the name of the question says it all.

I have some points to make before submitting the code:

  • If I know that a particular type of exception occurs in a particular set of statements, then should I use them in one attempt to immediately put the appropriate catch?
  • Or should I put all the error-prone code in one block of code and put all the corresponding catch blocks after this single attempt. Are there any performance costs associated with this?

    { try { exec();//can cause ExceptionXYZ } catch(ExceptionXYZ e){ } try { exec(); //can cause ExceptionPQR } catch(ExceptionPQR e){ } try { exec(); //can cause ExceptionABC } catch(ExceptionABC e){ } } 

Thus, the above method is good or lower than one

  { try { exec(); //can cause ExceptionXYZ exec(); // can cause ExceptionPQR exec(); //can cause ExceptionABC } catch(ExceptionXYZ e){ } catch(ExceptionPQR e){ } catch(ExceptionABC e){ } } 

It may also be possible to mix over two patterns, for example, nesting try in try . Any other considerations / points to be used when? . One thing is making sure that nesting complicates the code a bit.

In other scenarios, for example, when shutting down JDBC database resources, there are several other considerations (in the section ) in which we should handle each closure independently to ensure that one-way NullPointerException does not leave open resources:

  try { } catch(Exception e) { } finally { if (rs != null) //ResultSet try { rs.close(); } catch(SQLException se1) { se1.printStackTrace(); } if(pstmt!=null) //PreparedStatement try { pstmt.close(); } catch(SQLException se2) { se2.printStackTrace(); } if(conn!=null) //Connection try { conn.close(); } catch (SQLException se3) { se3.printStackTrace(); } } 

Any thoughts? Or just thinking too much.

Edit

Some additional considerations / facts (above thinking: p)

  • Just generalizing things: If at all there are some blocks of code, all of which must be executed in any case, then we should put them on a separate try-catch and any other code from these catch blocks should not cause any exceptions:

     { try { mustexec(); } catch(){ } noexceptionexec(); try { mustexec(); } catch() { } } 
  • Providing the smallest drop through catch () . If we are sure that a certain set of statements can cause a specific set of Exception, we should put these lines of code in the handler of the corresponding Exception instead of throwing it after an external attempt. Thus, above the third case (mix pattern) may be appropriate:

     { try { exec(); //can cause ExceptionXYZ } catch(ExceptionABC){ } catch(ExceptionPQR){ } catch(ExceptionXYZ){ } } 

Higher may be slightly inefficient than

  { try { try { exec(); //can cause ExceptionXYZ } catch(ExceptionXYZ){ } } catch(ExceptionABC){ } catch(ExceptionPQR){ } } 
+4
source share
9 answers

Code1 and Code2 are not equivalent.

 try{ exec1(); exec2(); // if exec1 fails, it is not executed }catch(){} try{ exec1(); }catch(){} try{ exec2(); // if exec1 fails, it is executed }catch(){} 

And for point 3 Yes. you can mix your code.

+7
source

If I present a catch block at all, I prefer to keep it closer to the code that might throw the corresponding exception, for the same reason why I declare variables closer to where they are used, i.e. better readability. For this reason, your first example is clearly preferable.

Combining try / catch with a sequence of if not so clean because reading your code requires a much better understanding of what happens on the exception handler block: in particular, in your example, the reader should know that only one condition will be true .

Despite the fact that sometimes it is necessary to handle exception handlers, as in the cleaning code, it is usual to β€œdelete” a second-level exception during cleaning, reporting only the first-level exception.

+3
source

It is also possible to use only one try-catch, see below:

 try { // some code that throws different exceptions } catch (Exception ex) { if (ex is ExceptionA) { //do something } else if (ex is ExeptionB) { //do something } } 

etc.

+1
source

Nested verses, not nesting, are a design decision. If you can recover from the exception, then investing seems good. If the exception is terminal, then no embedding seems good. Here is an example:

 try { try { ... code that may throw RecoverableException1 or TerminalException } catch (RecoverableException1 exception) { ... recover. Perhaps use default values and add a log entry. } try { ... code that may throw RecoverableException2 or TerminalException } catch (RecoverableException2 exception) { ... recover. Perhaps use default values and add a log entry. } } catch (TerminalException exception) { ... log the terminal exception and terminate. } 
+1
source

I think your main problems should be:

  • code correctness and then

  • code readability.

As others have pointed out, the two forms in your examples do not mean the same thing. There is a good chance that one of the forms is more correct than the other.

If you have two versions that are equally correct, the best version is the most readable version.

You cannot judge relative correctness or readability based on such artificial examples. So the bottom line is that there is no best practice rule for this decision.


Assuming the two versions of the code are equally valid and readable equally, there is a slight performance advantage when using multiple try / catch blocks compared to a single try / catch with multiple handlers. The thing is what happens when exceptions are handled. If there are several catch blocks, then the JVM makes the instanceof equivalent for each catch in turn until it finds one that matches (or exhausts them). If you have N catch blocks, this is up to N tests to be performed.

However, I must emphasize that the difference is small, and especially when you think that exceptions should be exceptional; those. you do not need to handle the exception in the vast majority of cases. (And if this assumption is incorrect, then you probably have more performance issues because the most expensive part of Java exceptions is usually the construction of the exception object.)

+1
source

You think too much about how you wrote. Just look at the official Oracle documentation at http://docs.oracle.com/javase/tutorial/essential/exceptions/catch.html and you will clearly see that the proposed way to handle the exception is

 try { } catch (ExceptionType name) { } catch (ExceptionType name) { } 
0
source

Entering and holding try / catch costs zero CPU time unless there are exceptions. Sending an exception from the corresponding catch block can probably cost a little more CPU if the method has many try / catch blocks, because the JVM must find the right catch among others. For me, you overdid it here.

0
source

The first (and perhaps the only) thing you should consider is to write the simplest and most understandable code. Only after you have a working application that may have performance problems, and you have profiled to determine that you have a measurable problem. You can compare alternatives to see if the other is better.

Until you install, you have a performance problem, I would like to write the simplest code that you can.

Note: can you assume that if an exception is thrown in the first block, you can continue as if it did not matter, often it is not, and it makes sense to wrap all the code in a try / catch block.

0
source

check try-with-resources , this should help ...

0
source

All Articles