Question on binary compatibility regarding default methods
Remi Forax
forax at univ-mlv.fr
Wed Mar 19 10:15:08 UTC 2014
On 03/19/2014 12:36 AM, Krystal Mok wrote:
> Hi all,
>
> I'm curious about a corner case of binary compatibility with regard to
> default methods and separate compilation (the source of many evils...). The
> example is run with JDK 8 build 132.
>
> Description:
>
> The starting point is that I've got an interface and an implementation
> class:
>
> public interface IFoo<E> {
> // empty
> }
>
> public class Foo implements IFoo<Foo> {
> public void bar(Foo o) {
> System.out.println("Foo.bar(Foo)");
> }
> }
>
> Both the interface and the implementation are compiled into Class files.
> Refer to this as ver1.
> Foo won't have any bridge methods on it at this point.
>
> Later on, the interface adds a default method, and is compiled separately,
> without recompiling the implementation class:
>
> public interface IFoo<E> {
> default void bar(E e) {
> System.out.println("IFoo.bar(E)");
> }
> }
>
> Refer to this as ver2.
>
> Then, another class uses the ver2 interface with the ver1 implementation
> class:
>
> public class Main {
> public static void main(String[] args) {
> Foo f = new Foo();
> f.bar(f); // (1) invokevirtual Foo.bar(Foo)void
>
> IFoo<Foo> i = f;
> i.bar(f); // (2) invokeinterface IFoo.bar(Object)void
> }
> }
>
> The output at (1) and (2) are:
> Foo.bar(Foo)
> IFoo.bar(E)
>
> My question is: is this the expected behavior according to the current
> spec, by design? I suppose it is.
yes
>
> The implementation in HotSpot seems to be only using the erased (name,
> signature) of bar(Object)void when searching candidates, so naturally it
> won't find the Foo.bar(Foo), and it can't find a bridge method for that
> because of separate compilation.
yes,
as you note to solve this issue you have to teach the VM the precise
semantics of Java generics.
The lambda EG has initially though it was a good idea to solve this
corner case so Keith McGuigan have done the daunting jobs to implement
in the VM the generation of bridges with all the corner cases related to
generics leading to awful issues like the fact that to generate bridges
you have to load more classes than necessary.
So we have backpedaled on that point considering that linking the VM
semantics to the Java type system was wrong and even evil.
It's obvious now and the lambda EG should have been more more
clairvoyant on that point (sorry Keith).
>
> Thanks,
> Kris
cheers,
Rémi
More information about the jdk8-dev
mailing list