Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Having a try-catch block, should you place ALL statements in it or just the unsafe one?

Suppose save throws and i is used only for save. Are the following code fragments the same? Please consider sematics, performance and other aspects.

void bob(){
  int i = calculate();
  try {
    save(i);
  } catch(Exception e){
    report(e)
  }
}

vs.

void bob(){
  try {
    int i = calculate();
    save(i);
  } catch(Exception e){
    report(e)
  }
}

Generally I want to know, should one place all statements of a function in a try-catch block or just the one throwing.

like image 376
Binary Bob Avatar asked Jun 20 '13 19:06

Binary Bob


2 Answers

Semantics-wise, if you have decided which method you're going to put your try-catch construct in (and you're comfortable that you've made that decision correctly), then the answer is fairly simple:

  • You should include in your try block a sequence of statements such that, if one of those statements fails, the rest of the sequence should be abandoned. No more and no fewer statements than that.

If you follow the above advice correctly, concerns such as the desired program flow and the most efficient scoping of the local variables will be resolved very easily and obviously (in most cases). You'll notice that this doesn't exclude the possibility of nested try blocks.

Performance-wise, the overhead of exception handling lies with actually throwing and catching a throwable object. In other words, there's really overhead only if an exception actually occurs. The mere presence of a try-catch construct in the code doesn't introduce any measurable overhead (possibly none at all). Also, the amount of statements (inside a given try-catch construct) is completely irrelevant to its performance.

Edit: I couldn't find any details in the JVM specification to link to, but there are many posts by users that examine and explain the generated bytecode, like this one and this one (among many others - a Google search will yield a few interesting results). To me, it looks like the Java compiler tries to emit as little as possible (except for, of course, the actual code you put in the try and the catch clauses and some inevitable program flow instructions to jump around said clauses or pop the exception object, if any). It leaves to the VM the responsibility of finding out where an exception is candidate to be caught. This most probably transfers more burden to the scenarios where the exception actually occurs but, as we know, exceptions are for exceptional cases, not control flow anyway.

I admit I have no idea how C++ exceptions are typically implemented, but it's very reasonable for them to radically differ from Java's, considering C++ programs don't usually run with the assistance of a VM.

like image 136
Theodoros Chatzigiannakis Avatar answered Sep 28 '22 08:09

Theodoros Chatzigiannakis


They are not the same. The difference is the scope of the variable i. In 2nd case, you cannot use i outside the try-catch block.

Generally I want to know, should one place all statements of a function in a try-catch block or just the one throwing.

The better way is to just wrap the code vulnerable to throwing exception inside the try-catch block. This way, you can handle specific exception related to specific block of codes. So, 1st way is the one to go for.

like image 24
Rohit Jain Avatar answered Sep 28 '22 08:09

Rohit Jain