extension method implementations for methods of java.lang.Object
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Thu Aug 19 05:09:44 PDT 2010
Thomas
I agree that this is a corner case of resolution rules described in the
defender method draft - however the current behavior (the one you see
when you execute the code compiled with the lambda compiler) has nothing
to do with such rules, as they are not implemeneted yet - just wanted to
make this clear.
Regarding the spec corner case, I think that what the rules are saying
here is that you have a class (B) that implicitly subclass from Object.
As such, Object.equals() implicitly overrides A.equals() and, as such,
must be chosen as the most specific implementation. At the end of the
day, defender methods are there to provide a default implementation for
an interface method where none is available in the superclass hierarchy;
in the unfortunate case of Object.equals() an implementation is indeed
available, as Object.equals() is a perfectly legal override for A.equals().
Note also that the following code works fine:
interface A {
boolean equals(Object o);
}
class Foo implements A {}
and the VM is already dispatching incoming calls to Foo.equals() into
Object.equals(), so I'm afraid that what you are proposing here would be
an incompatible change...
... but I'm sure Brian will have a better answer for you ;-)
Maurizio
On 19/08/10 12:35, Thomas Jung wrote:
> I thought this is due to the method resolution rules described in the
> latest draft of defender methods:
>
>
>> 3. Method dispatch
>> With an ordinary interface method invocation on a receiver of type D, first D is searched for a method implementation, then its superclass, and so on until we reach Object, and if an implementation is not found, a linkage exception is thrown. For an extension method, the search path is more complicated; first we search for actual implementations in D and its superclasses just as before, and if we do not find an implementation of the method in the implementation hierarchy, then we must search for the most specific default implementation among D’s interfaces (which is not a linear search), failing if we cannot find a unique most specific default.
>>
> According to the described rules the order for B a subclass of A is:
> B#equals, java.lang.Object#equals , A#equals. So the implementation in
> java.lang.Object is chosen as the most specific one.
>
> Thomas
>
> On 19 August 2010 10:50, Maurizio Cimadamore
> <maurizio.cimadamore at oracle.com> wrote:
>
>> On 19/08/10 08:59, Thomas Jung wrote:
>>
>>> Hi,
>>>
>>> with the current prototype it's not possible to define a default
>>> implementation for Object#equals.
>>>
>>> interface A{
>>> extension boolean xequals(Object obj) default As.eq;
>>> extension boolean equals(Object obj) default As.eq;
>>> }
>>>
>>> static class As{
>>> public static boolean eq(A me, Object object){
>>> throw new RuntimeException();
>>> }
>>> }
>>>
>>> a.equals(new Object()); //passes
>>> a.xequals(new Object()); //throws exception
>>>
>>> This feature is useful if the equals implementation for some subtypes
>>> of A can be expressed based on the methods defined in A.
>>>
>>>
>> The VM extension required to handle extension methods at runtime is not
>> available yet - as a result it is not possible to get to execute the above
>> code (or any code containing extension methods) with the right semantics...
>> in fact, since the runtime infrastructure is missing, the VM gets method
>> dispatching completely wrong - the invokevirtual targeting A.equals() is
>> dispatched to Object.equals() while for A.xequals() the VM complains because
>> it cannot find a suitable implementation of xequals() inside the instance
>> 'a'.
>>
>> Maurizio
>>
>>> -
>>> Thomas
>>>
>>>
>>>
>>
>>
More information about the lambda-dev
mailing list