类型擦除在Java中会导致多态的冲突,为了解决这一问题,JVM引入了泛型的 桥接方法 。
举例
假设有一个泛型类:
class Pair<T> {
private T value;
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
}
接着有一个子类继承它:
class DateInter extends Pair<Date> {
@Override
public void setValue(Date value) {
super.setValue(value);
}
@Override
public Date getValue() {
return super.getValue();
}
}
在子类中,设定父类的泛型类型为Pair<Date>,然而类型擦除后,父类的泛型类型全部变为了原始类型Object,导致多态的冲突。
为什么会出现这种情况?
原因在于虚拟机无法将泛型类型保留,只能将类型擦除掉,变为原始类型Object。这样,原本想要进行重写以实现多态的方法,变成了重载。为了解决这一问题,JVM采用了特殊的方法,即桥接方法。
桥接方法的原理
通过反编译子类的字节码,可以看到编译器生成了桥接方法,这些桥接方法的参数类型都是Object。这些桥接方法实际上是子类中真正覆盖父类方法的实现。虚拟机通过桥接方法来解决类型擦除和多态的冲突。
此外,值得注意的是,子类中的桥接方法 Object getValue() 和 Date getValue() 是同时存在的,这是因为虚拟机通过参数类型和返回类型来确定一个方法,因此编译器允许这种看似“不合法”的方法存在。
关于作者
本文由一线程序员Seven撰写,持续学习迭代中。文章已收录于作者的个人博客: https://www.seven97.top 。欢迎关注作者的公众号:seven97。
标签:游戏攻略