Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 7 - Precise rethrow with a final Exception

Tags:

In previous versions of java, rethrowing an exception was treated as throwing the type of the catch parameter.

For example:

public static void test() throws Exception{     DateFormat df = new SimpleDateFormat("yyyyMMdd");     try {         df.parse("x20110731");         new FileReader("file.txt").read();     } catch (Exception e) {         System.out.println("Caught exception: " + e.getMessage());         throw e;     } } 

In Java 7, you can be more precise about the exception being thrown, if you declare the exception final:

//(doesn't compile in Java<7) public static void test2() throws ParseException, IOException{     DateFormat df = new SimpleDateFormat("yyyyMMdd");     try {         df.parse("x20110731");         new FileReader("file.txt").read();     } catch (final Exception e) {         System.out.println("Caught exception: " + e.getMessage());         throw e;     } } 

My question: The docs say that I need to declare the Exception final. But if I don't, the code above still compiles and works. Am I missing something?

References:

Project Coin: multi-catch and final rethrow
Add more flexible checking for rethrown exceptions

like image 846
dogbane Avatar asked Jul 31 '11 11:07

dogbane


People also ask

Can you Rethrow an exception?

If a catch block cannot handle the particular exception it has caught, you can rethrow the exception. The rethrow expression ( throw without assignment_expression) causes the originally thrown object to be rethrown.

What is final Rethrow?

Final Rethow : Allows you to catch an exception type and it's subtype and rethrow it without having to add a throws clause to the method signature.

Can we Rethrow an exception in Java?

Java For TestersIf a catch block cannot handle the particular exception it has caught, we can rethrow the exception. The rethrow expression causes the originally thrown object to be rethrown.

How do you handle multiple exceptions in a single catch block in Java?

If a catch block handles multiple exceptions, you can separate them using a pipe (|) and in this case, exception parameter (ex) is final, so you can't change it. The byte code generated by this feature is smaller and reduce code redundancy.


2 Answers

I believe I saw a tweet from Josh Bloch saying that the "final" restriction had been lifted late on. I'll see if I can find a post about it, but I suspect it's just that any "early" documentation you read is now inaccurate.

EDIT: I can't find the exact "it's changed" post, but the Java 7 documentation states shows an example with it not being final. It talks about exception variables being implicitly final when a catch block declares more than one type, but that's slightly separate.

EDIT: I've now found the source of my confusion, but it's an internal mailing list post :( Anyway, it doesn't have to be declared as final, but I believe the compiler treats it as implicitly final - just like in the multi-catch scenario.

like image 162
Jon Skeet Avatar answered Sep 30 '22 08:09

Jon Skeet


The reason why both compile is that an exception in a uni catch clause that is not subsequently modified is implicitly final (JLS 14.20).

So for your example not to compile, you need to modify e in some way, for example:

public static void test2() throws ParseException, IOException {     DateFormat df = new SimpleDateFormat("yyyyMMdd");     try {         df.parse("x20110731");         new FileReader("file.txt").read();     } catch (Exception e) {         if (e instanceof ParseException) {             e = new ParseException("Better message", 0);         } else {             e = new IOException("Better message");         }         System.out.println("Caught exception: " + e.getMessage());         throw e; //does not compile any more     } } 
like image 34
assylias Avatar answered Sep 30 '22 08:09

assylias