Why does javac use "invokespecial" for diamond inheritance?

Rafael Winterhalter rafael.wth at gmail.com
Mon Oct 3 10:13:29 UTC 2016


I am wondering why javac is using an invokespecial instruction for a bridge
method in the following case. Considering the following refactoring
starting from:

class A {
  public void m(String s) {
    System.out.println("foo");
  }
}

class B extends A { }

class C extends B {
  public void m(String s) {
    System.out.println("bar");
  }
}

I would change the implementing of B to implement an additional interface:

interface I<T> {
  void m(T t);
}

class B extends A implements I<String> { }

C would live in its own module that is not recompiled upon changing B. I do
however not consider this a problem as the change of B is binary
compatible. However, B ends up with the following bridge method:

class B extends A implements I<String> {
  public bridge void m(Object o) {
    Foo.special.m((String) o);
  }
}

If a program does now invoke I::m on an instance of C, "foo" is printed
instead of "bar". This violates the intended virtual dispatch for C. In my
opinion, this should not happen. Bridge methods, unless "visibility
bridges" should always use invokevirtual as an override in C, should make
it impossible to invoke A::m directly from outside the class.

Did I miss something here or is this a bug?

Thank you for the clarification,
Best regards, Rafael
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20161003/d687e9a3/attachment-0001.html>


More information about the compiler-dev mailing list