感觉泛型中的桥方法挺难理解的,写篇笔记记录一下(具体是core java第536页,我的理解可能会有偏差)。
如下面的两段代码:
public class Pair<T> { private T first; private T second; public Pair() { first = null; second = null; } public Pair(T first, T second) { this.first = first; this.second = second; } public T getFirst() { return first; } public T getSecond() { return second; } public void setFirst(T newValue) { first = newValue; } public void setSecond(T newValue) { second = newValue; } }
class DateInterval extends Pair<Date> { public void setSecond(Date second) {} }
由于类型擦除的原因,DateInterval存在两个setSecond方法,分别为:
public void setSecond(Date second) //自身创建
public void setSecond(Object second) //继承自Pair<Date>
考虑以下调用:
DateInterval interval = new DateInterval(...);
Pair<Date> pair = interval;
pair.setSecond(aDate);
由于java语言的多态性,pair理论上应该调用DateInterval.setSecond方法。但是根据上面的分析,DateInterval类存在两个setSecond方法,到底该如何调用呢?
JVM工作原理如下:
1. 变量pair声明为Pair<Date>,该类型只有一个setSecond(Object)方法,虚拟机用pair引用的对象去调用这个setSecond(Object)方法。
2. pair引用的对象是DateInterval,所以将会调用DateInterval.setSecond(Object)方法,这个方法是桥方法。
3. 这个桥方法会调用DateInterval.setSecond(Date)方法。
桥方法代码:public void setSecond(Object second) { setSecond((Date) second); } //仔细看方法内部的Date强制类型转换,使得桥方法调用了DateInterval.setSecond(Date)方法
桥方法有时候会变得十分奇怪,假设DateInterval方法也覆盖了getSecond方法:
class DateInterval extends Pair<Date> { public Date getSecond() { return (Date) super.getSecond().clone(); } }
擦除类型后,DateInterval有两个getSecond方法:
Date getSecond() //自身创建
Object getSecond() //继承自Pair<Date>
咦,方法的签名不是“方法名+参数”吗?为什么会存在签名一样,返回类型不一样的方法呢?实际上,在JVM中,返回类型是可以用来区分方法的,虚拟机能够正确处理这一情况。