Hi Rémi, Great! Thanks a lot for your answer. That's what I'm looking for.
I do remember that at one point there was a piece of code in the VM that injected bridge methods, but I didn't follow the development of this area later, so I thought the VM was still doing that, but it isn't. So I was a bit confused and needed clarification. Now I've got it :-) Thanks, Kris On Wednesday, March 19, 2014, Remi Forax <fo...@univ-mlv.fr> wrote: > 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 > >