泛型中的桥接方法
声明一个抽象类
public abstract class BaseMapper<T> {
public abstract T selectByPrimaryKey(T t);
}
再声明其子类
public class UserMapper extends BaseMapper<User> {
@Override
public User selectByPrimaryKey(User user) {
// 方法体
}
}
单纯获取子类中声明的方法,会发现子类竟然有两个方法
for (Method method : UserMapper.class.getDeclaredMethods()) {
System.out.println(method.toGenericString());
System.out.println(method.isBridge());
}
打印结果如下
public User fool.liyc.liyclearn.basic.genericTest.UserMapper.selectByPrimaryKey()
fasle
public Object fool.liyc.liyclearn.basic.genericTest.UserMapper.selectByPrimaryKey()
true
多出来的第二个方法就是一个桥接方法,会发现生成的class文件里根本没有这个方法,但是却可以打印关于它的日志。
其原理是:
针对于继承泛型类并重写泛型方法的情况
class B extends A<String> {
//它就是桥接方法
Object get(Object s) {
return (Object) get((String) s);
}
String get(String s) {
return "";
}
}
如果子类中的方法只有 String get(String s) 方法,那显然并没有完成对父类中T get(T s) 方法的重写,由于泛型擦除,它应该重写成Object get(Object s),否则会因为抽象方法没被重写而报错,但写上又会让开发人员感觉莫名其妙多个个方法。
jdk1.5以后为了解决这个问题,引入了桥接方法的概念,在运行时增加桥接方法用于适配方法重写机制,再隐藏起来让人不可见,所以才会出现"明明子类只声明了一个方法,却能遍历出两个DeclareMethod"的情况。