不使用反射如何调用某个实例对象的方法

本文转载自不使用反射如何调用某个实例对象的方法

导语

如何调用一个对象的方法?我们可以通过实例化对象直接调用、使用反射机制、通过代理对象等,本文介绍一种新的方法MethodHandle,这种方法在开发中很少会用到,但使用起来感觉很顺手。

什么是MethodHandle?

MethodHandle是JDK1.7实现了JSR-292,新加入的java.lang.invoke包中的一个重要组成部分,这个包的主要是在单纯通过符号引用来确定调用的目标方法以外,提供一种析的动态确定目标方法的机制。

示例

package com.bk.exercise;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
/**
 * @author BK
 * @description:
 * @date 2019-08-19 22:34
 */
public class MethodHandlerTest {
    static class Person{
        public void sing(String songName){
            System.out.println("I'm sing " + songName);
        }
    }
    /**
     * 实现调用Person类的sing方法
     * @param args
     */
    public static void main(String[] args) throws Throwable {
        Person zhangsan = new Person();
        // void.class是方法返回的类型    String.class 是方法的入参类型
        MethodType mt = MethodType.methodType(void.class,String.class);
        MethodHandle handler = MethodHandles.lookup()
                //找到zhangsan对象中签名和mt指定的签名是一致的sing方法
                .findVirtual(zhangsan.getClass(), "sing", mt)
                //非静态方法的第一个参数隐藏的this指针,这步相当设置第一个参数this指针
                .bindTo(zhangsan);
        handler.invokeExact("Summer train ");
    }
}

运行结果如下显示

I'm sing Summer train

从示例可以看出来,使用MethodHandle并没有什么困难,可以实现方法的调用,可是很多人会问,反射不也可以做相同的事情么,我们经常会使用反射,而不会使用这种方法。

MethodHandle与Reflection的区别

如果站在Java语言的角度来看,他们确实是有很多相似之处,但是从他们其它角度来看,确有很大的区别

  1. 从本质上来讲,ReflectionMethodHandle机构都是在模拟方法调用,但Reflection是模拟的Java代码层面的方法调用,而MethodHandle是在模拟字节码层面的方法调用。
  2. Reflection中的Method是重量级的,MethodHandle对象是轻量级的,Reflection中包含了方法的签名、描述符以及方法属性表中各种属性、执行权限等,而MethodHandle仅仅包含与执行该方法相关的信息
  3. MethodHandle是字符码的方法指令调用模拟,理论上可以模拟出和JVM上一样的优化如方法内联,但是Reflection去调用方法则不可以
  4. Reflection API的设计目标是为Java语言服务的,而MethodHandle设计成可服务于所有Java虚拟机之上的语言

写在最后

MethodHandles.lookup中的findStatic()findVirtual()findSpecia()三个谅正是为了对应invokestaticinvokevirtual&invokeinterface、invokespecial这几条字节码指令的执行权限校验行为,本文中只讲到了findVirtual()方法,其它两个方法读者可以自行尝试一下。

java.lang.invoke包中的内容可以看一看,别有一番有洞天。

posted @ 2020-06-27 12:33  Yungyu  阅读(972)  评论(0编辑  收藏  举报