Java interface synthetic method generation while narrowing return type

Roman Lebedev :

I have 2 interfaces, and 2 return types.

interface interfaceA {
   Publisher<String> doSomething();
}

interface interfaceB extends interfaceA {
   Flow<String> doSomething();
}

interface Publisher<T>{}
class Flow<T> implements Publisher<T>{}

So at runtime, I can see 2 methods of interfaceB.class.getMethods()

  1. public default my.package.Publisher my.package.interfaceB.doSomething()

  2. public abstract my.package.Flow my.package.interfaceB.doSomething()

Regarding the first one, it is Synthetic. (method.getModifiers() & 0x00001000 > 0) == true

Does java autogenerate this synthetic methods?

How does it work in general?

Johannes Kuhn :

What you see here is called a bridge method.

To understand why this is needed, we have to look at how the JVM determines if two methods are different:

  • Every method has a name. Different name -> different method.
  • Every method has a descriptor. Different descriptor-> different method.

The descriptor contains all arguments and the return type (with generics, it's erasure).

From the JVM perspective Flow doSomething() is a different method than Publisher doSomething(), so when it is asked to do a invokeinterface call to Publisher doSomething() it won't call Flow doSomething().

This can happen if the target at the callsite is of type interfaceA:

intefaceA foo = ...;
foo.doSomething();

But from the language perspective, both methods are the same, and one overrides the other.

To restore this relationship, javac adds a bridge method with the original method type that just calls the overloaded method.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=309753&siteId=1