JAVA反射 | 桥接方法 method.isBridge()

桥接方法是 JDK1.5 引入泛型后,为了使泛型方法生成的字节码与之前版本的字节码兼容,由编译器自动生成的方法。

通过代码可以更好地理解:

声明一个泛型接口

public interface A<T> {
    void test(T t);
}

使用 String 类型实现一个具体的实现类

public class B implements A<String> {
    public void test(String s) {
        System.out.println(s);
    }
}

泛型本身是语言级别的,经过编译后,泛型就会被擦除,所以接口 A 在编译后,test 方法的入参会被转换为 Object

public interface A {
    void test(Object t);
}

实现类 B 中的实现方法是 void test(String s),其实根本就没有实现 void test(Object t) 方法。但是这个代码是正确的,可以正常运行,因为 JVM 在编译过程中对我们的实现类做了一点手脚

public class B implements A {
    public void test(String s) {
        System.out.println(s);
    }
    public void test(Object s) {
        this.test((String) s);
    }
}

编译后的类 B 也擦除了泛型,但是增加了一个方法同名的 test 方法,这个方法是代码中没有的,由 JVM 在编译期生成,是接口 Atest 方法的真正实现方法,这个方法就叫做桥接方法

通过反射验证一下

public class Test {
    public static void main(String[] args) {
        Class<B> classB = B.class;
        Method[] methods = classB.getDeclaredMethods();

        System.out.println("方法总数量:" + methods.length);
        for (Method method : methods) {
            System.out.println(method.getReturnType().getSimpleName() + " "
                    + method.getName() +
                    "(" + method.getParameters()[0].getType().getSimpleName() + ")"
                    + " is " + (method.isBridge() ? "bridge" : "common") + " method"
            );
        }
    }
}

输出如下

方法总数量:2
void test(String) is common method
void test(Object) is bridge method

一般项目中泛型的使用都是非常频繁的,使用反射进行一些公共逻辑处理时,突然遇到一个代码中没有的方法时,不要慌张,因为那可能是一个桥接方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值