Exception transparency
Rémi Forax
forax at univ-mlv.fr
Thu Jun 10 15:50:02 PDT 2010
Le 10/06/2010 23:48, Alex Buckley a écrit :
> I believe the short answer to this is "yes".
>
> Alex
>
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
}
}
Rémi
> On 6/10/2010 2:41 PM, Peter Levart wrote:
>
>> Hello Maurizio,
>>
>> What if compiler would track internally any type variable with Throwable bound in such a way
>> that when used in any context except "throw" statement it would mean lub(X,Y,Z,...) as defined
>> today but when used in throw statement it would mean X|Y|Z|...
>>
>> class Foo<X> { void set(X x) {} }
>>
>> class A extends Exception {}
>>
>> class B extends Exception {}
>>
>> class Test {
>>
>> static<E extends Exception> Foo<E> test(E e1, E e2) throws E {
>> switch (new Random().nextInt(3)) {
>> case 0: throw e1;
>> case 1: throw e2;
>> default: return new Foo<E>();
>> }
>> }
>>
>> public static void main(String args) {
>> try {
>> test(new A(), new B()).set(new Exception());
>> }
>> catch (A a) {}
>> catch (B b) {}
>> }
>>
>> }
>>
>>
>> Would that work? Would that be back compatible?
>>
>> Regards, Peter
>>
>>
>> On Tuesday, June 08, 2010 02:25:40 pm Maurizio Cimadamore wrote:
>>
>>> On 08/06/10 13:13, Maurizio Cimadamore wrote:
>>>
>>>> On 08/06/10 12:54, Peter Levart wrote:
>>>>
>>>>> On 06/08/10, Maurizio Cimadamore wrote:
>>>>>
>>>>>>>> needs to guess any intentions where it will affect realistic code.
>>>>>>>>
>>>>>>> Neal,
>>>>>>> I have trouble to figure out an example of such rare places.
>>>>>>>
>>>>>>> Do you have an example of such code ?
>>>>>>>
>>>>>> Could be this?
>>>>>>
>>>>>> class A<X> extends Exception {}
>>>>>> class B extends A<String> {}
>>>>>> class C extends A<Integer> {}
>>>>>>
>>>>>> <throws E> E choose(E e1, E e2) { ... }
>>>>>>
>>>>>> choose(new B(), new C()); //what is the inferred type for E???
>>>>>>
>>>>>> In JDK 5/6 E is inferred to be A<? extends Object& Comparable<?
>>>>>> extends Object& Comparable<?>>>. In JDK 7 with the proposed new
>>>>>> semantics for 'exception-bound' type-vars the inferred type would be
>>>>>> something like A<String> | A<Integer>, which, I guess, would need to
>>>>>> be rejected as an ill-formed type on the grounds of type-disjointness
>>>>>> (A<String> and A<Integer> are not provably distinct).
>>>>>>
>>>>> Are you suggesting to relax the rule that generic classes can not extend
>>>>> Throwable?
>>>>>
>>>> Good catch - my example is illegal; no incompatibility here.
>>>>
>>> I tried harder ;-) :
>>>
>>> class Foo<X> { void set(X x) {} }
>>>
>>> class A extends Exception {}
>>> class B extends Exception {}
>>>
>>> class Test {
>>> static<E extends Exception> Foo<E> test(E e1, E e2){ return new
>>> Foo<E>(); }
>>>
>>> public static void main(String args) {
>>> test(new A(), new B()).set(new Exception());
>>> }
>>> }
>>>
>>> This compiles in JDK 5/6 (E inferred to be Exception); it fails to
>>> compile under JDK 7 if we assume that type-variables with Exception
>>> bound have a 'varadic' semantics; in fact in this case the type A|B
>>> would be inferred. But this means that you cannot pass an Exception
>>> where an A|B is expected.
>>>
>>> Maurizio
>>>
>>>
>>>> Maurizio
>>>>
>>>>
>>>>> Peter
>>>>>
>>>>>
>>>>>> Maurizio
>>>>>>
>>
>
More information about the lambda-dev
mailing list