Hi, Kris, It seemed a synthetic method was added when the "famous" Java generics joining. You may need to consult experts in lambda-...@openjdk.java.net:)
Jin On Wed, Mar 19, 2014 at 7:36 AM, Krystal Mok <rednaxel...@gmail.com> 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. > > 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. > > Thanks, > Kris >