Final defenders
David Holmes
david.holmes at oracle.com
Wed Aug 8 02:32:51 PDT 2012
Aleksey,
I think this just highlights that default methods are not intended to be
what you are trying to make them. They exist to provide an
implementation where none would otherwise exist, not to be an enforced
and non-overridable implementation. They might look like traits from a
certain angle but they are at best a very limited form.
If Java needs traits (I said "if"!) then add traits, but don't try to
contort interfaces into traits. A language will only stretch so far
before it breaks.
My 2c.
David
On 8/08/2012 12:34 AM, Aleksey Shipilev wrote:
> Hi,
>
> TRAITS! Now, while Brian is gasping with exertion, I'll continue. While
> studying the it2-bootstrap branch code, I have come across using
> defenders in trait-like fashion:
>
> public interface StatefulOp<T, U, V> {
> public boolean isStateful() default {
> return true;
> }
> }
>
> In this case, the defender is not particularly the fallback default, but
> really an enforced implementation. However, lacking language support for
> these cases, I can do:
>
> public class MyRogueOp implements StatefulOp {
> public boolean isStateful() {
> return false; // eat that!
> }
> }
>
> ...and the defender rules will count my concrete implementation as
> legitimate one. This makes relying on isStateful() quite a bad idea in
> the library.
>
> That makes me thinking if we need to embrace it, and realize that some
> of the defenders are really final. My suggestion is simple: let's mark
> the final defenders "final"!
>
> In simplest form:
>
> public interface StatefulOp<T, U, V> {
> public final boolean isStateful() default {
> return true;
> }
> }
>
> "final" is not allowed in interfaces by the current rules, so we can use
> this loophole to introduce a new meaning. However, this feels wrong to
> provide the default implementation, and instantly forbid the extension.
> So, maybe this is better:
>
> public interface StatefulOp<T, U, V> {
> public boolean isStateful() final {
> return true;
> }
> }
>
> This should be more complicated to implement in compiler, but it clearly
> mandates the method body is the final implementation.
>
> This is not completely enforceable in the compile time, and so it
> complicates the method dispatch a bit. We need to check if there is any
> superclass final defender in the hierarchy, that can piggyback on the
> defender selection we have now. Also, two colliding defenders, no matter
> if the pairs are default/final, default/default, or final/final should
> render the same error as default/default collision now.
>
> Additional concern is the evolution. We need to explore two things:
> 1. Can we add "final" to the defender on the existing interface?
> 2. Can we remove "final" from the defender on the existing interface?
>
> The answer to both seems to be "yes", because the same class of bugs we
> have already with abstract classes and visibility rules, also
> unenforceable with separate compilation. We can still do compile-time
> checks so that code compiled at once would never throw a linkage error.
>
> Thoughts?
>
> -Aleksey.
>
More information about the lambda-dev
mailing list