Formal model for defender method resolution

David M. Lloyd david.lloyd at
Mon Jan 31 18:31:34 PST 2011

Honestly I don't think of this as re-abstraction.  It's the *default* 
implementation, not *the* implementation.  You're saying, "if nobody 
else in the hierarchy says otherwise, do this".  Especially if the 
syntax is different.

Anyway, if someone has re-overridden a defender method it probably means 
they did so *before* the defender method existed, and they probably 
already have an implementation for it so it doesn't matter.  If they 
override a defender method after the fact, they'd probably change the 
default if they wanted to.

That said it would be nice if one could *explicitly* remove the default 
implementation by overriding it.  Maybe "default abstract" or something.

On 01/31/2011 08:19 PM, Brian Goetz wrote:
> All things being equal, I would agree with (1) and (3).  Unfortunately
> reabstraction of defended methods seems to complicate resolution, and
> given that people use reabstraction fairly infrequently now, it may be a
> better choice to accept some additional apparent inconsistency in
> exchange for simpler semantics.
> I am not sure I agree with (2), because it is not uncommon to see an
> overriding purely to add a note to the Javadoc, enough so that
> supporting reabstraction "breaks" the common intuition that
> (non-covariantly) overriding a method in an interface is a no-op.
> On 1/31/2011 8:56 PM, Howard Lovatt wrote:
>> Hi,
>> I think it is best that a defended method can be re-abstracted (like
>> abstract classes currently do) for three reasons:
>> 1. It is the expected behaviour. If you see "m();" in an interface,
>> you expect it to be abstract and you expect to have to implement it.
>> You should not be required to check the hierarchy to see if it is
>> inheriting something unexpected. If you forget to implement the method
>> you won't be warned, silently and potentially insidiously a default
>> will appear.
>> 2. It is the only safe assumption. If someone is overriding a defended
>> method then they are doing so for some good reason. Commonly, the
>> semantics of the method are subtly altered and a modification to the
>> Javadoc is required to note the change. The fact that the semantics
>> have changed means that inheriting the method isn't safe and therefore
>> it should be re-abstracted.
>> 3. It is important to be consistant with abstract classes, since
>> defender methods are similar to abstract classes and it will be
>> confusing if they behave differently. People may well start to use
>> defender methods were they previously used abstract classes, therefore
>> the two should be as interchangeable as possible.
>> Cheers,
>>    -- Howard.
>> On 29 January 2011 13:03, David Holmes<David.Holmes at>   wrote:
>>> Alex,
>>>    >   Again, why do defenders if defending a method in a top superinterface
>>>    >   is going to be undone by "accidental" overriding (by rather hopeless
>>>    >   abstract methods) in subinterfaces?
>>> Let's not forget that the primary use-case for defenders is to allow us
>>> to add _new_ methods to interfaces together with an implementation so
>>> that (most) existing classes will continue to compile and execute
>>> correctly. Adding defenders to existing methods is not the primary
>>> use-case and as per past discussions is somewhat perilous.
>>> The crux of this matter is "accidental overriding" versus "deliberate
>>> overriding". If I override an interface method f() in B to specialize it
>>> compared to how it is defined in A then not only do I not want to
>>> inherit A's defender for f(), it would be inherently incorrect to do so
>>> because it does not implement the correct semantics.
>>> You seem to want to cater for the programmer who accidentally overrides
>>> f() (to tweak javadoc in a semantically non-changing way) to still get a
>>> defender that exists somewhere in the inheritance hierarchy. Whereas I
>>> (and I think others) expect overriding (with no explicit defender) to
>>> mean reabstraction of the method.
>>> Why are you against reabstraction? Reabstraction is always safe, if not
>>> always convenient. Silent inheritance may be convenient for some but is
>>> potentially unsafe.
>>> Why should the addition of a defender in a super interface break my
>>> framework by allowing subclasses to silently inherit use of a defender
>>> that doesn't implement the semantics of the current type?
>>> David Holmes
>>> Alex Buckley said the following on 01/29/11 11:06:
>>>> On 1/28/2011 3:55 PM, Neal Gafter wrote:
>>>>> Die due to no f impl, exactly as it does today.  In this case it is
>>>>> irrelevant that one of the newly added methods has a default, as that
>>>>> default could not possibly be the one that the call resolves to.  This
>>>>> is a situation that occurs today and that is indeed what happens.
>>>> Why bother with defenders if a call to a defended method (and I think
>>>> C.f _is_ defended by A.f, despite B.f) is going to die at runtime?
>>>> Not sure what you mean by "that default could not possibly be the one
>>>> that the call resolves to." The caller who causes execution of
>>>> invokeinterface B.f()B; has no idea whether the receiver class
>>>> implements f via a defender or via declaration/class inheritance.
>>>>>       If there's no error for B, and B.f _does_ inherit A.f's default, then
>>>>>       invokeinterface B.f()B on a C may return an A that's not a B, and we
>>>>>       definitely have unsoundness.
>>>>> Agreed!  Which is why B.f should not inherit A.f's default.
>>>>>       So either there should be an error on B;
>>>>> Huh?  Why?  This is a simple case of reabstraction.  There's nothing
>>>>> wrong with B.  There might or might not be something wrong with some
>>>>> further derived type, but B is fine.
>>>> It's not reabstraction if A.f is given a defender after B gains f.
>>>> Defending the highest superinterface alone seems like a common migration
>>>> path, one we should support.
>>>>>       or no error yet _B.f inherits
>>>>>       A.f's default and the inherited defender is typechecked in its new
>>>>>       environment_.
>>>>> Huh?  Why?  When you reabstract a method, it has no implementation to
>>>>> inherit or check.
>>>> Again, why do defenders if defending a method in a top superinterface is
>>>> going to be undone by "accidental" overriding (by rather hopeless
>>>> abstract methods) in subinterfaces?
>>>> Alex


More information about the lambda-dev mailing list