zoukankan      html  css  js  c++  java
  • java反射的补充:桥接方法以及Spring中一些工具类

    在上一篇博文中:http://www.cnblogs.com/guangshan/p/4660564.html

    源码中有些地方用到了

    this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);

    那么bridgedMethod是什么呢?

    经查找发现,这个叫做桥接方法:http://freish.iteye.com/blog/1158008

    java编译器采用bridge方法来兼容本该使用泛型的地方使用了非泛型的用法的问题。

    如下代码:

    public class TestBridgeMethod {
        public static void main(String[] args) {
            P p = new S();
            p.test(new Object());
        }
    }
    
    class P<T> {
        public T test (T t){
            return t;
        }
    }
    
    class S extends P<String> {
        @Override
        public String test(String t) {
            return t;
        }
    }

    p引用的是S的对象,但S的test方法返回值是String,在jdk1.4中没有泛型,就不会对p.test(new Object());进行检查,这样在调用的时候就会报ClassCastException

    声明p的时候使用P<String> p就不会有这样的问题了。

    为了兼容非泛型的代码,java编译器为test生成了两个方法。看下面的代码:

    import java.lang.reflect.Method;
    import java.util.Arrays;
    
    
    public class TestBridgeMethod {
        public static void main(String[] args) {
            Class<?> clazz = S.class;
            Method[] methods = clazz.getMethods();
            for(Method method : methods) {
                System.out.println(method.getName() + ":" + Arrays.toString(method.getParameterTypes()) + method.isBridge());
            }
        }
    }
    
    class P<T> {
        public T test (T t){
            return t;
        }
    }
    
    class S extends P<String> {
        @Override
        public String test(String t) {
            return t;
        }
    }

    运行结果为:

    test:[class java.lang.String]false

    test:[class java.lang.Object]true

    getClass:[]false

    hashCode:[]false

    equals:[class java.lang.Object]false

    toString:[]false

    notify:[]false

    notifyAll:[]false

    wait:[long, int]false

    wait:[]false

    wait:[long]false

    编译器为S生成了两个test方法,一个参数为String,用于泛型。一个参数为Object,用于非泛型,这个方法就是bridge方法,调用method.isBridge返回true。

    之前提到的没有正确使用泛型时会导致越过类型检查,就是桥接方法引起的。

    还有一些很有用的spring源码中的util工具集合:

    http://www.cnblogs.com/younggun/p/3247262.html

  • 相关阅读:
    gridview列前加复选框需要注意的一点
    为什么日历控件放在panel无法显示出来
    表格翻页
    The SDK platform-tools version ((21)) is too old to check APIs compiled with API 23
    win7怎么安装和启动 jboss
    (转)如何制作nodejs,npm “绿色”安装包
    Can't use Subversion command line client: svn
    (转)Android自定义属性时format选项( <attr format="reference" name="background" /> )
    本地拒绝服务漏洞修复建议
    (转)Android 读取联系人(详细)
  • 原文地址:https://www.cnblogs.com/guangshan/p/4661305.html
Copyright © 2011-2022 走看看