Java interface synthetic method generation while narrowing return type

≡放荡痞女 提交于 2020-06-27 16:39:08

问题


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?


回答1:


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.




回答2:


The Java Language Specification specifies the following:

A construct emitted by a Java compiler must be marked as synthetic if it does not correspond to a construct declared explicitly or implicitly in source code, unless the emitted construct is a class initialization method

Another definition I've seen from Java Papers is:

When an enclosing class accesses a private attribute of a nested class, Java compiler creates synthetic method for that attribute.

EDIT: It was pointed out that some of what this article states applies to an older Java version (SE7), so be mindful when reading online papers.

So for example:

import static java.lang.System.out;

public class Synthetic {

  public static void main(String[] arguments) {
      Synthetic.NestedClass nested = new Synthetic.NestedClass();
      out.println("Age: " + nested.age);
  }

  private static final class NestedClass {
      
      private String myName = "Tom";

      private int age = 42;

  }

}

The compiler will create synthetic methods for every private attribute being accessed. So, it'll create synthetic method (static int access$000(Synthetic$NestedClass)) for age, but not myName



来源:https://stackoverflow.com/questions/58065680/java-interface-synthetic-method-generation-while-narrowing-return-type

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!