Extension method and covariant return type

Rémi Forax forax at univ-mlv.fr
Mon May 17 01:28:24 PDT 2010


I think there is something which is not specified: how covariant return type
(and generics) interacts with the extension method.

Suppose I have something like that:

public interface Iterable<E> {
   extension <F> Iterable<F> map(F(E) lambda)
     default Collections.<E, F>iterableMap(F(E));
}

public interface Collection<E> implements Iterable<E> {
   extension <F> Collection<F> map(F(E) lambda)
     default Collections.<E, F>collectionMap(F(E));
}

Currently when method that aren't defender method,
the compiler adds a bridge (ACC_BRIDGE) method
to all classes that implements the interfaces
to do the bridge between the methods.

Because defender methods can be inserted at runtime,
the compiler can not add this bridge
(the class can be compiler with a non 1.7 compiler).
But the compiler can add another defender method that will do the bridge:

public interface Collection<E> implements Iterable<E> {
   extension <F> Collection<F> map(F(E) lambda)
     default Collections.<E, F>collectionMap(F(E));

   extension <F> Iterable<F> map(F(E) lambda)
     default (Collection<F>)Collection<E>.map(F(E)); // brige inserted 
by the compiler
}

This means that the spec must be changed a little to allow to
reference method that aren't static and with a slighty different signature
(bridge can require to cast parameter).
Note that because defender bridges are only added by the compiler,
the Java spec can only authorize static default but the JVM spec
must authorize reference to virtual method + casts
(Hotspot already have call stubs to insert casts without requiring a 
full stack frame).

A question remains, should declaration of extension method allowed in class
(not only in interface) to retrofit standard bridge mecanism to always
use defender bridge.

Rémi






More information about the lambda-dev mailing list