Java反射中method.isBridge() 桥接方法

桥接方法是 JDK 1.5 引入泛型后,为了使Java的泛型方法生成的字节码和 1.5 版本前的字节码相兼容,由编译器自动生成的方法。我们可以通过Method.isBridge()方法来判断一个方法是否是桥接方法。

假定接口

public interface SuperClass<T> {
    void method(T t);
}

它的一个实现类

public class AClass implements SuperClass<String> {
    @Override
    public void method(String s) {    System.out.println(s);  } }

因为泛型是在1.5引入的,为了向前兼容,所以会在编译时去掉泛型(泛型擦除)。那么SuperClass接口中的method方法的参数在虚拟机中只能是Object。

它应该是这个样子:

public interface SuperClass {
    void method(Object  t);
}

而 AClass 实现了SuperClass 接口,但是它的实现方法却是:

    public void method(String s) {
    System.out.println(s);
  } 

根本就没有实现 void method(Object t) 方法。 这怎么回事,其实虚拟机自动实现了一个方法。

AClass在虚拟机中是这个样子:

public class AClass implements SuperClass  {
    public void method(String s) {
        System.out.println(s);
    }
    public void method(Object s) {
         this.method((String) s);
    }
}

这个void method(Object s)  就是桥接方法。

我们用这个命令查看

javap -p AClass.class

显示如下:

Compiled from "AClass.java"
public class AClass implements SuperClass<java.lang.String> {
  public AClass();
  public void method(java.lang.String);
  public void method(java.lang.Object);
}

我们用反射写个测试,看结果如何

    public static void main(String[] args) throws Exception {
        AClass obj = new AClass();
        Method m = AClass.class.getMethod("method", String.class);
        m.invoke(obj, "XXXXXXXXXXXXXXXXXX");
        System.out.println(m.isBridge());
        m = AClass.class.getMethod("method", Object.class);
        m.invoke(obj, "##################");
        System.out.println(m.isBridge());
    }

测试结果如下

XXXXXXXXXXXXXXXXXX
false
##################
true
时间: 2024-10-06 22:19:09

Java反射中method.isBridge() 桥接方法的相关文章

java反射中method类中的invoke方法作用

首先Method类代表一个方法,所以invoke(调用)就是调用Method类代表的方法.它可以让你实现动态调用,例如你可以动态的传人参数.下面是一个简单的例子. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 public class MethodTest {     public static void main(String[] args)

java中什么是bridge method(桥接方法)

最近在看spring-mvc的源码,看到在解析handler方法的时候,有关于获取桥接方法代码,不明白什么是桥接方法,经过查找资料,终于理解了什么是桥接方法. 什么是桥接方法 桥接方法是 JDK 1.5 引入泛型后,为了使Java的泛型方法生成的字节码和 1.5 版本前的字节码相兼容,由编译器自动生成的方法. 我们可以通过Method.isBridge()方法来判断一个方法是否是桥接方法,在字节码中桥接方法会被标记为ACC_BRIDGE和ACC_SYNTHETIC,其中ACC_BRIDGE用于说

JAVA反射中的getFields()方法和getDeclaredFields ()方法的区别

关于获取类的字段有两种方式:getFields()和getDeclaredFields().我们先来看看这两者的区别吧: getFields():获得某个类的所有的公共(public)的字段,包括父类中的字段. getDeclaredFields():获得某个类的所有声明的字段,即包括public.private和proteced,但是不包括父类的申明字段. 同样类似的还有getConstructors()和getDeclaredConstructors().getMethods()和getDe

java反射的补充:桥接方法以及Spring中一些工具类

在上一篇博文中:http://www.cnblogs.com/guangshan/p/4660564.html 源码中有些地方用到了 this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); 那么bridgedMethod是什么呢? 经查找发现,这个叫做桥接方法:http://freish.iteye.com/blog/1158008 java编译器采用bridge方法来兼容本该使用泛型的地方使用了非泛型的用法的问题

JAVA深入研究——Method的Invoke方法。

在写代码的时候,发现从父类class通过getDeclaredMethod获取的Method可以调用子类的对象,而子类改写了这个方法,从子类class通过getDeclaredMethod也能获取到Method,这时去调用父类的对象也会报错.虽然这是很符合多态的现象,也符合java的动态绑定规范,但还是想弄懂java是如何实现的,就学习了下Method的源代码. Method的invoke方法 1.先检查 AccessibleObject的override属性是否为true. Accessibl

JAVA深入研究——Method的Invoke方法

http://www.cnblogs.com/onlywujun/p/3519037.html 在写代码的时候,发现Method可以调用子类的对象,但子类即使是改写了的Method,方法名一样,去调用父类的对象也会报错,虽然这是很符合多态的现象,也符合java的动态绑定规范,但还是想弄懂java是如何实现的,就学习了下Method的源代码. Method的invoke方法 1.先检查 AccessibleObject的override属性是否为true. AccessibleObject是Met

JAVA深入研究——Method的Invoke方法(转)

在写代码的时候,发现Method可以调用子类的对象,但子类即使是改写了的Method,方法名一样,去调用父类的对象也会报错,虽然这是很符合多态的现象,也符合java的动态绑定规范,但还是想弄懂java是如何实现的,就学习了下Method的源代码. Method的invoke方法 1.先检查 AccessibleObject的override属性是否为true. AccessibleObject是Method,Field,Constructor的父类,override属性默认为false,可调用s

在java反射中 Class.forName和classLoader的区别

解释 在java中,Class.forName()和ClassLoader()都可以对类进行加载,ClassLoader就是遵循双亲委派模型最终调用启动类加载器的类加载器,实现的功能是"通过一个类的全限定名来获取描述此类的二进制字节流",获取到二进制流后放到JVM中.Class.forName()方法实际上也是调用的CLassLoader来实现的. Class.forName(String className)这个方法的源码是: 最后调用的方法是forName0这个方法,在这个forN

Eclipse Class Decompiler——Java反编译插件手工配置方法

最近在eclipse上配置了java反编译插件,但是不好用,原因是我的eclipse之前有手动配置过一些类似的java反编译插件,当我将原来的插件完全卸载后重新配置才正常配置上去,自动配置java反编译插件请参考博客Eclipse Class Decompiler--Java反编译插件,非常感谢版主chensuper的分享.这里仅描述我手动配置该插件的过程. 插件离线下载的地址:http://feeling.sourceforge.net/downloads/org.sf.feeling.dec