Final defenders

Yuval Shavit yshavit at akiban.com
Tue Aug 7 10:20:55 PDT 2012


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? The
only thing I can think of is if it's used as a generic type:
Collection<StatefulOp> or such. But then, what would you do with an
instance of StatefulOp? The only thing you'd be able to do without
reflection is call isStateful() (and presumably assert that the result is
true), which isn't particularly useful.

I think your example would be more interesting as something like:

abstract class Op<T,U,V> {
    protected abstract boolean isStateful();

    public void doWhatever() {
        if (isStateful()) { ... }
        else { ... }
    }

}

public interface StatefulOp {
    public boolean isStateful() default {
        return true;
    }
}

public interface StatelessOp {
    public boolean isStateful() default {
        return false;
    }
}

class MyOp<T,U,V> extends Op<T,U,V> implements StatefulOp { } // mixin!

Now you have a mixin, but it's also not meaningful to say that your op can
"go rogue." For instance, if you had:

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.

Going back to my first paragraph, a final defender method _can_ be useful
if it invokes some other method on the interface:

public interface StatefulOp {
    boolean hasState();

    public boolean isStateful() default { // for interface evolution, or
whatever
        return hasState();
    }
}

Now, you can go rogue pretty easily:

class RogueOp implements StatefulOp {
    @Override
    public boolean hasState() {
        return true;
    }

    @Override
    public boolean isStateful() {
        return false;
    }
}

So in this example, you could make an argument for isStateful's defender
being final. But if you think about it not in terms of defender methods,
but in terms of interfaces and contracts, I would say that you've violated
the StatefulOp's contract that hasState() == isStateful(). 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?

Also, what would happen if two interfaces both declare a method as final?
Do you get to pick one (in which case, you can violate the other's
contract, thus defeating the whole point of final defender methods)? Do you
get to implement your own version of the method, in effect circumventing
the final? Or do you not get to implement both interfaces, in which case
you lose out even if both implementations are identical?

On Tue, Aug 7, 2012 at 12:49 PM, Daniel Latrémolière <
daniel.latremoliere at gmail.com> wrote:

>
> >   - What about static methods: being considered by the EG
> Interesting. I hope this will be used in collections to avoid direct use
> of implementing classes and allow programming only with used interface
> (in many use-cases):
>
> public interface List {
>      ...
>      public static List createRandomAccess() {
>          return new ArrayList();
>      }
>
>      public static List createSequentialAccess() {
>          return new LinkedList();
>      }
>
> }
>
> Thanks,
> Daniel Latrémolière.
>
>


More information about the lambda-dev mailing list