[9] RFR (M): 8050052: Small cleanups in java.lang.invoke code

Peter Levart peter.levart at gmail.com
Wed Jul 16 18:20:40 UTC 2014


On 07/16/2014 05:14 PM, Peter Levart wrote:
> On 07/15/2014 09:51 PM, John Rose wrote:
>> On Jul 11, 2014, at 10:56 AM, Remi Forax <forax at univ-mlv.fr> wrote:
>>
>>> On 07/11/2014 06:18 PM, Vladimir Ivanov wrote:
>>>> http://cr.openjdk.java.net/~vlivanov/8050052/webrev.00
>>>> https://bugs.openjdk.java.net/browse/JDK-8050052
>>> I've found myself writing the very same code as 
>>> MethodHandleStatics.uncaughException several times
>>> and I wonder if it should not be an instance method of Throwable.
>>> Something like:
>>>
>>> public <E extends Throwable> E rethrow(Function<? super Throwable, ? 
>>> extends E> uncaughtHandler) {
>>>   if (this instanceof RuntimeException) {
>>> throw (RuntimeException)this;
>>>   }
>>>   if (this instanceof Error) {
>>>     throw (Error)this;
>>>   }
>>>   return uncaughtHandler.apply(this);
>>> }
>>>
>>> in that case, throw uncaughtException(ex) can be replaced by throw 
>>> ex.rethrow(::newInternalError);
>> That's not a bad idea, but (odd for me to say this) it is too easy to 
>> use.
>>
>> Occasionally there are reasons for *locally* subverting static 
>> checking of exceptions, usually because we are writing a framework 
>> (like jli) that is polymorphic across exception types.  The checking 
>> is suppressed in one place so it can be reasserted elsewhere, usually 
>> with some concerted wrapping and unwrapped (aka exception 
>> tunnelling).  An API which assists in doing this would be helpful, 
>> but it should be highly specific.  In effect it should say "I am 
>> temporarily suppressing all checked exceptions except the locally 
>> checked ones X, Y, Z, and tunnelling the rest through a wrapper W."
>
> try {
>     ...
> } catch (X | Y | Z e) {
>     throw e;
> } catch (Throwable t) {
>     throw new W(t);
> } 

Ops, it should be:

try {
     ...
} catch (X | Y | Z | RuntimeException | Error e) {
     throw e;
} catch (Throwable t) {
     throw new W(t);
}

... and it's not so concise any more.

And it's easy to make a mistake ;-). But Remi is right when he says that 
an API does not have to be concerned about managing locally checked X, 
Y, Z since they can be handled by normal catch block(s) before the last 
catch (Throwable).

About the name of such Throwable instance method (using Stream terminology):

mapIfChecked(Function); // ElseThrow is implicit


An alternative could be:

public Throwable throwIfUnchecked() {
     if (this instanceof RuntimeException) throw (RuntimeException) this;
     if (this instanceof Error) throw (Error) this;
return this;
}

Then use it like:

     try {
         ...
     } catch (Throwable t) {
         throw new WrapperException(t.throwIfUnchecked());
     }


Regards, Peter





More information about the core-libs-dev mailing list