Exception transparency

Alex Buckley alex.buckley at oracle.com
Thu Jun 10 16:13:55 PDT 2010


On 6/10/2010 3:50 PM, Rémi Forax wrote:
> Please, I don't want to explain why //1 and //2 aren't equivalent.
> 
> class Test {
>   static<E extends Exception>  E test(E e1, E e2) {
>     return (Math.random()<  0.5)? e1: e2;
>   }
> 
> 
>   static<E extends Exception>  void test(E e1, E e2) throws E {
>     throw (Math.random()<  0.5)? e1: e2;
>   }
> 
>   public void main(String[] args) {
>     throw test1(new A(), new B());   //1
> 
>     test2(new A(), new B());  //2
>   }
> }

A throws clause is already implicitly understood as disjunctive. No-one 
is surprised if you say a method "throws A or B". That's what 'void 
test' as invoked by //2 _should do_.

People _will_ be surprised if you say the 'E test' method "returns A or 
B". For this reason, an exception type parameter that may be inferred as 
disjunctive may only be used as a type argument or in a throws or catch 
clause; your E is a bare return type.

Currently we're thinking that E is _not_ an exception type parameter; 
it's a normal type parameter that would continue to be inferred as 
Exception for //1. Declare '<throws E extends Exception>' to get proper 
disjunctive inference, but then you can only throw, not return, E.

Obviously we would be better off if type parameters that extend checked 
exception types had not been allowed when generics came in.

Alex


More information about the lambda-dev mailing list