我有 2 个接口(interface)和 2 个返回类型。
interface interfaceA {
Publisher<String> doSomething();
}
interface interfaceB extends interfaceA {
Flow<String> doSomething();
}
interface Publisher<T>{}
class Flow<T> implements Publisher<T>{}
所以在运行时,我可以看到interfaceB.class.getMethods()
的2个方法
公共(public)默认 my.package.Publisher my.package.interfaceB.doSomething()
公共(public)抽象 my.package.Flow my.package.interfaceB.doSomething()
关于第一个,它是合成的。 (method.getModifiers() & 0x00001000 > 0) == true
java会自动生成这个合成方法吗?
一般来说它是如何工作的?
最佳答案
您在这里看到的称为桥接方法。
要理解为什么需要这样做,我们必须看看 JVM 如何确定两个方法是否不同:
- 每个方法都有一个名称。不同的名称 -> 不同的方法。
- 每个方法都有一个描述符。不同的描述符->不同的方法。
描述符包含所有参数和返回类型(使用泛型,它会被删除)。
从 JVM 角度来看,Flow doSomething()
是与 Publisher doSomething()
不同的方法,因此当要求它对 Publisher 执行 invokeinterface 调用时doSomething()
它不会调用 Flow doSomething()
。
如果调用站点的目标类型为 interfaceA
,就会发生这种情况:
intefaceA foo = ...;
foo.doSomething();
但是从语言的角度来看,这两种方法是相同的,并且一种方法会覆盖另一种方法。
为了恢复这种关系,javac
添加了一个桥接方法,其原始方法类型仅调用重载方法。
关于Java 接口(interface)合成方法生成,同时缩小返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58065680/