实现通用java接口增加了额外的方法
我有一个通用java接口Id<T>
,其中有一个方法T getId()
,还有一个实现Id<Long>
的类MyClass
。当我使用java反射检查MyClass
上声明的方法时,我看到两个方法:一个是返回类型Long
,另一个是返回类型Object
。第二种方法从何而来?如何删除它
以下是消息来源:
package mypackage;
import java.lang.reflect.Method;
public class MainClass {
public static void main(String[] args) {
for (Method method : MyClass.class.getDeclaredMethods()) {
System.out.println(method);
}
// prints out two lines
// public java.lang.Long mypackage.MyClass.getId() <-- ok
// public java.lang.Object mypackage.MyClass.getId() <-- not ok
}
}
interface Id<T> {
T getId();
}
class MyClass implements Id<Long> {
@Override
public Long getId() {
return new Long(0);
};
}
# 1 楼答案
您可以通过
javap -c MyClass
找到编译后的方法:正如你所看到的,
getId
有2个方法,一个返回类型是Long
作为implementation
,另一个返回类型是Object
类型(它调用了Long getId
方法)返回类型
Object
方法用于在没有指定泛型类型和桥接到Long getId
方法时进行处理。例如:作为上面的代码片段,我们可以用
Long
类型实现Id
匿名类。但是问题是,我们也可以实现Id
匿名类,比如不在变量中指定泛型类型:所以现在编译器不能为变量
id
推断泛型类型,当id.getId()
它返回类型Object
类型变量时,这意味着它调用这个方法public java.lang.Object getId();
并连接到public java.lang.Long getId();
方法# 2 楼答案
这就是我们的特色。同样的问题也在报告中提出
JDK-8060179 Class.getDeclaredMethods() returning inconsistent results with generics并以“不是bug”结束
# 3 楼答案
第二种方法是
synthetic bridge
方法,您可以用method.isSynthetic()
或method.isBridge()
检查它。您不能删除它,但如果不想在声明的方法列表中看到它,只需检查所有这些方法是否有isBridge() == false
在编译过程中,合成桥方法会自动添加到泛型类中。你可以阅读更多关于合成方法的内容