Exception transparency
Alex Buckley
alex.buckley at oracle.com
Thu Jun 10 14:14:32 PDT 2010
On 6/9/2010 1:23 AM, Maurizio Cimadamore wrote:
> On 09/06/10 00:44, Neal Gafter wrote:
>> > Function<throws IOException> e = #(IOException e){...};
> Hi
> just to be clear, on which basis would you reject the above statement? I
> guess your argument is that a lambda accepting an argument of type E
> cannot be SAM-converted to an interface whose method accepts an argument
> of type 'throws E' (and, more generally, that E and 'throws E' are not
> interchangeable). Am I reading correctly?
Neal points out that exception type arguments are not covariant:
interface Function<throws E> { void m(Function<throws E> fe) throws E; }
Function<throws IOException> e = #(Function<throws IOException> x){};
Function<throws Exception> f = e; // Assume this is OK
Function<throws SAXException> g = #(Function<throws SAXException> x){};
try {
f.m(g);
// f.m statically expects a Function<throws Exception>,
// so an actual param of Function<throws SAXException> is OK.
// Or is it? f.m really expects a Function<throws IOException>.
catch (Exception ex) {}
Nathan Bryant pointed this out too, albeit rather tersely. We had hoped
to ban exception type parameters in many locations, such as a bare E for
a method's formal parameter type, while allowing them in other
locations, notably as exception type arguments _in_ formal parameter
types. But _any_ appearance in a contravariant context is no good.
Also, as Nathan said, exception type arguments are not contravariant either:
Function<throws Exception> e =
#(Function<throws Exception> x){ throw new SAXException(); };
Function<throws IOException> f = e; // Clearly unsafe
(And even if it was OK, contravariant exception type arguments couldn't
appear in any covariant context, such as a return type, and thus their
utility would be restricted, dual to Neal's comment.)
Alex
More information about the lambda-dev
mailing list