Final defenders

Aleksey Shipilev aleksey.shipilev at oracle.com
Tue Aug 7 11:10:52 PDT 2012


Hi Yuval,

On 08/07/2012 09:20 PM, Yuval Shavit wrote:
> Given that an interface doesn't have state, and a method on that interface
> which returns a value without invoking any other method on the interface,
> what does a final defender method give you that an annotation doesn't? 

This is the tidbit: StatefulOp is the functional interface, and so is
the candidate for lambda conversion. Final defenders in this sense allow
to mark the specific and irrevocable "flavors" of lambdas. Granted, in
this case one can bury the head in the sand, and stop worrying about
someone implementing StatefulOp as the concrete class and pretending it
is a lambda of specific flavor. I would better stop them from doing that.

> class MyOp<T,U,V> extends RogueOp<T,U,V> implements StatefulOp {
>     @Override
>     public boolean isStateful() default {
>         return false;
>     }
> }
> 
> ... then is your op rogue, or is it simply stateless by virtue of using a
> mixin that says it's stateful, but then overriding that mixin? I would
> argue the latter.

That feels like a strong argument. For my taste, overriding the metainfo
from the marker interface (really, this is the marker with final
metainfo), you are violating the purpose of having this marker, and so
this code is rogue, and should be forbidden. That is the whole point of
having final defenders: not allowing anyone to change its meaning.

> Sure, a final
> defender method would have saved you, but is it worth adding that feature
> just to address one specific (and I don't suspect significant) class of
> contract violations?

Even this contrived example has the potential to catastrophic failure.
One of the suggested optimizations is caching the pipelines of
operations. We can do that once we figure all operations are stateless
(easy case), or reset to initial state if stateful (hard case).

Hence, we can have drastically different behavior for different
properties of isStateful(), and the this way rogue op will create an
irrevocable mess. I would like to detect this tricky runtime error as
compile- or linkage-time error. And yes, I tend to think it is worth
adding even if it is about this single case. Unless you have better
suggestion for this?

> Also, what would happen if two interfaces both declare a method as final?

As I said in the original proposal it is the same kind of collision as
we have now in default/default collision case. It is a linkage error to
have ambiguous final pair.

-Aleksey.



More information about the lambda-dev mailing list