Method isBridge&isSynthetic&isVarArgs

Method.isBridge

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

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

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.Object] => true
wait => [long] => false
wait => [long, int] => false
wait => [] => false
equals => [class java.lang.Object] => false
toString => [] => false
hashCode => [] => false
getClass => [] => false
notify => [] => false
notifyAll => [] => false

如上:在为兼容JDK 1.5一下的 JDK ,P 为字节码表示为:

class P{   
    public Object test(Object t) {
         return t;
    }
}

但在 P子类中test 的 方法参数为 String,,故 JVM 自动帮我们生成 父类的桥接实现 test(Object t) 。

Method.isSynthetic()

Method.isSynthetic()方法断定如果指定方法是合成方法,


import java.lang.reflect.Method;


import static java.lang.System.out;

public class TestSynthetic {
    public static void main(String[] args) {
        new TestSynthetic().testSynthetic();
    }

    public void testSynthetic() {
        try {
            User user = new User();
            user.setAge( 1);
            Method[] methods = User.class.getDeclaredMethods();
            for (Method method : methods) {
                out.println(method.toString() + ", " + method.isBridge());
            }
        } catch (SecurityException e) {
            e.printStackTrace();
        }
    }

    class User {
        private int age;
        private String name;

        private User() {
        }

        private User(int age, String name) {
            this.age = age;
            this.name = name;
        }

        private int getAge() {
            return age;
        }

        private void setAge(int age) {
            this.age = age;
        }

        private String getName() {
            return name;
        }

        private void setName(String name) {
            this.name = name;
        }

    }
}

类中由private修饰的成员,只能被该类自身所访问,因此嵌套类的私有成员不应该能被外部类访问。另一方面嵌套类虽然在外部类里面,但其实并不属于外部类的一部分,比如编译上边的代码会得到两个.class文件,Inner类被编译成了package可见的独立类。

 TestSynthetic$1.class
 TestSynthetic$User.class
 TestSynthetic.class

可实际代码里,内部类和外部类之间互相调用对方的私有成员却没有任何的编译错误,这其中就是合成方法在起作用。

即可以简单理解为 非代码中编写而,JDK 帮助我们生成的方法。

联系上文桥接方法,得知,桥接方法也是JDK 帮助我们生成的,故桥接方法也是合成方法,但合成方法不一定是桥接方法

Method.isVarArgs()

通过Method.isVarArgs() 来区别是否是可变参数。 :

import java.lang.reflect.Method;

public class MethodDemo {
    public static void main(String... args) {
        Method[] methods = MethodDemo.class.getDeclaredMethods();
        for (Method method : methods) {
            System.out.print(method.getName() + "=>");
            System.out.println(method.isVarArgs());
        }
    }

    public void main2(String[] args) {
        Method[] methods = MethodDemo.class.getDeclaredMethods();
        for (Method method : methods) {
            System.out.print(method.getName() + "=>");
            System.out.println(method.isVarArgs());
        }
    }
}

结果

main2=>false
main=>true
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值