Final defenders

Aleksey Shipilev aleksey.shipilev at oracle.com
Tue Aug 7 07:34:37 PDT 2012


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