15

I am checking out the new features of Java SE7 and I am currently at this point:

http://docs.oracle.com/javase/7/docs/technotes/guides/language/catch-multiple.html

regarding the catch multiple feature, when I came across this statement:

Note: If a catch block handles more than one exception type, then the catch parameter is implicitly final. In this example, the catch parameter ex is final and therefore you cannot assign any values to it within the catch block.

I never noticed that the caught exception is not final in the classic case of handleing caught exceptions.

I just wonder why is that a good thing in the first place? Would it not be ill-advised to essentially MODIFY a caught exception before I guess rethrowing it or maybe logging it's message? Should it not be up to the trowing mechanism to create the exception so it represents exactly what it should?

I have never seen an exception being modified in the catch block can maybe someone point out it's benefits?

Peter Jaloveczki
  • 2,039
  • 1
  • 19
  • 35
  • Uh, good one, I didn't even know it was not final in the "single exception" case... – fge Jun 06 '13 at 10:20
  • what would be the difference if it was final since only the catch block knows of this object? does it matter if you rethrow this object or another one? in most cases the exception if wrapped in another one and rethrown. if it was final you could still rethrow a modified copy. – Marco Forberg Jun 06 '13 at 10:29
  • The only reason I could think of is if you wanted to edit or add to the stack trace for some reason using the setStackTrace() method on the exception. – MasNotsram Jun 06 '13 at 10:35
  • 2
    being `final` doesnt preserve the exception's methods from being called - no matter if they modify the exception or not. `final` is no synonym for `const` in C – Marco Forberg Jun 06 '13 at 10:37
  • 1
    Oh I misread the question, I thought it meant the class was final not the object. In that case, it may not give you an answer, but a similar question with discussion has taken place here: http://www.coderanch.com/t/607092/Java/java/Handling-Exception-Catch-Block – MasNotsram Jun 06 '13 at 10:42
  • There is no doubt about what final means. Also no doubt that you "could" make a copy for whatever reason if you wanted to. In a nutshell: The question is why would you ever want to overide the exception reference? – Peter Jaloveczki Jun 06 '13 at 10:54

4 Answers4

4

It's pretty much the same as method arguments:

You usually don't modify them and many people agree that they should be treated as final (whether or not to actually write final in front of them is a matter of some debate).

But since there's no technical requirement that says it must be final, the language gives you the option to choose.

Personally I know of no good reason to modify the exception reference of a catch-block.

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
  • Pretty interesting point! I guess it makes sense, however still I feel like that this case is a little bit special. I for one would consider modifying and exception in any way after it is caught a bad practice. Thanks a lot for your attention! – Peter Jaloveczki Jun 06 '13 at 10:42
  • @user1960804: keep in mind that "modifying the exception" (via some method calls) and the *reference* being `final` are orthogonal (one of those doesn't influence the other)! – Joachim Sauer Jun 06 '13 at 10:43
  • Yes i know, I must say I still feel the same way taking that under consideration. It's more like about the nature of the final keyword at that point. – Peter Jaloveczki Jun 06 '13 at 10:45
3

I cannot think of a convincing use-case for modifying an exception in a classic catch clause. However, that doesn't mean it should be forbidden. Especially given that you can modify a parameter variable. If you find this worrisome, you have the option of declaring the exception variable to be final.

On the other hand, allowing modification in the multi-exception catch would introduces the possibility of truly bizarre and confusing code such as this:

  catch (IOException | NullPointerException ex) {
      ...
      ex = new IllegalArgumentException(...);
  }

I imagine that's what the designers had in mind when they added the restriction in this case.

But either way, this is how the Java language is defined, and what we have to live with. There's not a lot of point in debating the apparent inconsistencies ... unless you are intending to design and implement a new language.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • No doubt, however understanding the language always puts everyone closer to develop the best code. I actually asked the question to find out if there is any viable reason for someone to modify the reference itself. I will not implement a new language any time soon. : / Thanks for your attention! – Peter Jaloveczki Jun 06 '13 at 11:22
  • Is catch (IOException | NullPointerException ex) new syntax in Java 7? – selig Jun 06 '13 at 11:31
  • Yep! You can read all about it through the link I have added in the question. http://docs.oracle.com/javase/7/docs/technotes/guides/language/catch-multiple.html – Peter Jaloveczki Jun 06 '13 at 11:40
0

The reason I can think of to enforce it final is due to performance. Once the catch evaluation starts, having a final immutable value in the mechanics of the evaluation ensures a faster evaluation of all catches. Since try-catch is extensively used throughout any java code, the highest performance design is preferable.

Based on the above, it implies a performance improvement that affects most programs.

gextra
  • 8,439
  • 8
  • 40
  • 62
  • I did not thought about that, I wonder what other people have to say about this? – Peter Jaloveczki Jun 06 '13 at 10:49
  • 2
    I don't think it would make any difference, performance-wise. The JIT compiler is perfectly capable of working out if a local variable changes after its initial assignment ... and optimizing based on that. It doesn't *need* a `final` hint, either implicitly or explicitly. – Stephen C Jun 06 '13 at 11:26
0

The idea behind exception-based error handling is that each error should be recovered, if at all possible, at the appropriate level of abstraction. Such error recovery might require information that is not directly available where the exception is actually handled. For this reason it might be convenient to catch the exception, augment it with the relevant information and rethrow it or possibly set it as cause of a new exception object of a more appropriate class.

Nicola Musatti
  • 17,834
  • 2
  • 46
  • 55
  • None of that requires assigning a new value to the variable and none of that is prevented by having the exception itself be final though. Sorry for bumping this, someone just edited a 6 year old post for removing a 'thanks'. – Sebastiaan van den Broek Jun 23 '19 at 06:48