javac warnings for multi-catch

David Holmes David.Holmes at oracle.com
Wed Apr 27 00:34:59 PDT 2011


Gernot Neppert said the following on 04/27/11 16:56:
> Interesting observation!
> One might argue that the compiler warning points to a flaw in the
> original code: even though it 'works' as intended,
> it's not really 'clean code'. The author obviously did not trust the
> official API of task.run().

We do not trust the programmers that implement run(). The code we right 
is robust in the face of user-defined code that does unexpected things. 
The code might "innocently" invoke Class.newInstance for a class where 
the constructor can throw a checked-exception.

> If he had, catching RuntimeException and Error would have sufficed.
> Rather, he wanted to catch 'sneaky' checked Exceptions, too.
> So he used 'catch Throwable' to cover for that, even though there are
> no Throwable-derivatives other than 'Error' and 'Exception'.

Users can define their own subclass of Throwable - which would be a 
checked exception of course.

> To sum it up, I'd suggest the following code as a better, more concise
> way of expressing the intent:
> 
> try {
>            task.run();
>      } catch (Exception x) {
>                   thrown = x; throw x;
>      } catch (Error x) {
>                   thrown = x; throw x;
>      } finally {
>                  afterExecute(task, thrown);
>      }
> 
> Does the Java-7 compiler issue a warning for this, too?

Don't know but it can't be used because the Exception is checked and so 
we can't rethrow it unless we declare it.

David


> 
> 2011/4/26 David Holmes <David.Holmes at oracle.com>:
>> I have a query regarding the warnings that javac now issues that are
>> related to the work on multi-catch that does more precise analysis of
>> the exceptions that can be thrown. Here's an example:
>>
>> ../../../src/share/classes/java/util/concurrent/ThreadPoolExecutor.java:1115:
>> warning: unreachable catch clause
>>                     } catch (Throwable x) {
>>                       ^
>>   thrown types RuntimeException,Error have already been caught
>>
>> and here's the code:
>>
>>                     try {
>>                         task.run();
>>                     } catch (RuntimeException x) {
>>                         thrown = x; throw x;
>>                     } catch (Error x) {
>>                         thrown = x; throw x;
>>                     } catch (Throwable x) {
>>                         thrown = x; throw new Error(x);
>>                     } finally {
>>                         afterExecute(task, thrown);
>>                     }
>>
>> This pattern is not uncommon. The final catch of Throwable is there to
>> close the gap that exists because of the API's (Class.newInstance) that
>> allow you to throw checked-exceptions from methods that don't declare
>> them. So the catch clause is not in fact unreachable.
>>
>> It seems to me that these warnings will encourage people to remove the
>> "offending" catch clause and actually end up with code that is not
>> robust because of these historical flaws in the API's (not to mention
>> native calls).
>>
>> Perhaps it would be better to restrict the warnings to the cases where a
>> previous clause will catch the exception expected by the later clause,
>> rather than incorrectly assuming which exceptions can be thrown from the
>> methods in the try-block.
>>
>> David
>>
>>



More information about the coin-dev mailing list