我有 2 个接口和 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()
public default my.package.Publisher my.package.interfaceB.doSomething()
public abstract my.package.Flow my.package.interfaceB.doSomething()
关于第一个,它是合成的。(method.getModifiers() & 0x00001000 > 0) == true
java会自动生成这个合成方法吗?
它一般如何运作?
您在这里看到的称为桥接方法。
要理解为什么需要这样做,我们必须看看 JVM 如何确定两个方法是否不同:
- 每个方法都有一个名称。不同的名称 -> 不同的方法。
- 每个方法都有一个描述符。不同的描述符->不同的方法。
描述符包含所有参数和返回类型(对于泛型,它是擦除的)。
从JVM角度来看Flow doSomething()
是一种不同的方法Publisher doSomething()
,因此当要求执行 invokeinterface 调用时Publisher doSomething()
它不会打电话Flow doSomething()
.
如果调用点的目标类型为interfaceA
:
intefaceA foo = ...;
foo.doSomething();
但从语言的角度来看,这两种方法是相同的,并且一种方法会覆盖另一种方法。
为了恢复这段关系,javac
添加一个具有原始方法类型的桥接方法,该方法仅调用重载方法。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)