Java方法句柄 MethodHandle介绍

news/2024/5/19 4:41:14 标签: Java, Android, 反射

MethodHandle是干什么用的

说到反射大家肯定都很清楚,但是不一定知道MethodHandle。那么MethodHandle是干啥的?MethodHandle实现了Java反射的大部分功能,但它实际上是一种函数指针,非常类似于C++的函数指针。 有的文章称之为“现代化反射”。其实它和反射还是有很大的差别的。

  • 从本质上讲,反射是模拟Java代码层次级别的调用,而MethodHandle是模拟字节码层次级别调用。
  • 反射中Method对象包含的信息要比MethodHandle包含的信息多,包含了方法的签名,描述符以及方法属性表中各种属性的Java端表达方式,以及执行全线等信息。
  • MethodHandle是针对字节码级别的应用,所以它是针对所有的JVM语言的,而反射仅仅是Java语言级别的应用。

MethodHandle有什么应用

反射

反射一样,但是比反射效率要高,因为直接是操作字节嘛。另外他是内联的,效率更高。

支持动态语言

我们知道JVM的发展方向是支持动态语言的,在JAVA 8中就已经支持了lambda表达式。还有一些其他的动态jvm语言,比如最近很火热的Kotlin。JVM中使用
invokedynamic这条新的指令。

MethodHandle使用例子

如何使用,先看步骤

1,获取MethodType对象。

  //第一个参数是返回值的类型,后面的参数是方法的参数类型。
    MethodType m=MethodType.methodType(....);

2,获取Looup对象。

   MethodHandles.Lookup lookup = MethodHandles.lookup();

3,获取MethodHandle对象

MethodHandle methodHandle = lookup.findVirtual(MHTest.class,"toString",mt);

4,调用方法

    String s = (String) methodHandle.invokeExact(test,"nihao");

上述步骤,大家一定要记住,有了步骤。就按照步骤来写个例子吧。

package com.nanguiyu;


public class MethodTest {


   public String mh(String str){
       return str;
   }



}


package com.nanguiyu;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;

public class Test {
    public static void main(String[] args){
        MethodType mt = MethodType.methodType(String.class,String.class);
        MethodHandles.Lookup lookup = MethodHandles.lookup();
        try {
            MethodTest methodTest = new MethodTest();
            MethodHandle methodHandle = lookup.findVirtual(MethodTest.class,"mh",mt);
            String message = (String) methodHandle.invoke(methodTest,"Hello,World");
            System.out.println(message);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
    }
}

MethodHandle 不能访问私有方法,是一个轻量级的反射。另外还必须获取到要反射类的对象。说到这里,大家是不是觉得有点奇怪。
获取了对象的实例,还反射啥,直接调用不就行了吗?那我们就先反射得到对象,然后在反射方法。

package com.nanguiyu;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;

public class Test {
    public static void main(String[] args){
        MethodType mt = MethodType.methodType(String.class,String.class);
        MethodHandles.Lookup lookup = MethodHandles.lookup();
        try {
            MethodType methodType = MethodType.methodType(void.class);
            MethodHandle methodTest = lookup.findConstructor(MethodTest.class,methodType);
            MethodTest m = (MethodTest) methodTest.invoke();
            MethodHandle methodHandle = lookup.findVirtual(MethodTest.class,"mh",mt);
            String message = (String) methodHandle.invoke(m,"Hello,World");
            System.out.println(message);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
    }
}

大功告成了。


http://www.niftyadmin.cn/n/869727.html

相关文章

2021-05-12

什么是活码生成器?活码有什么用?有没有免费的? 1,什么是活码? 活码生成器是一种动态二维码生成软件,又称为动态二维码,或者活码,和静态二维码相比较是具有灵活性,是一种…

pythondecode函数 attributeerror_Python 常见问题汇总

在使用python过程中,遇到一些常见的问题,整理汇总如下:1、常见错误列表异常描述NameError尝试访问一个没有声明的变量ZeroDivisionError除数为0SyntaxError语法错误IndexError索引超出序列范围KeyError请求一个不存在的字典关键字IOError输入…

arrayvalue php,在PHP中最好使用$ array [] = $ value或array_push

没有基准&#xff0c;但是我个人感觉看起来$array[]更干净一些&#xff0c;并且诚实地在几毫秒内拆分头发是无关紧要的&#xff0c;除非您计划在数组中添加成千上万个字符串。编辑&#xff1a;运行此代码&#xff1a;$t microtime(true);$array array();for($i 0; $i < 1…

php二次开发模板,HYPHP框架二次开发-(1)模板开发

小灰灰在使用HYPHP这个轻量级框架之后就爱不释手了&#xff0c;&#xff0c;&#xff0c;(自己不会写框架)但是使用过程中也有部分不如意的地方&#xff0c;比如Model模型&#xff0c;比如模板引擎等。今天闲着没事用笨代码完善了一丁点模板引擎代码。(我新人&#xff0c;勿喷)…

MATLAB1阶零模型,MATLAB/simulink控制系统之离散系统模型(0基础)

目录5.6 离散系统5.6.1 离散空间模型(1)直接创建systf(num,den,’Ts’);%建立传递函数模型,Ts为采样周期&#xff1b;(2)连续系统离散化sysd c2d(sys,Ts);sysd c2d(sys,Ts,’method’);其中sys为输入的连续系统传递函数模型或状态空间模型;sysd为离散化所得的离散系统传递函数…

php模板图片加载不出,thinkPHP分组后模板无法加载问题解决方法

本文分析了thinkPHP分组后模板无法加载问题解决方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;一个分组简要的目录结构如下图所示&#xff1a;默认分组配置为Home。当访问localhost/server/时可以正常访问前台&#xff0c;localhost/server/home/Index/index也能…

matlab求解关键,基于遗传算法的多辆洒水车最优路径求解(其中包含MATLAB的一些关键语句说明和Floyd,Dijkstra,Euler算法).doc...

基于遗传算法的多辆洒水车最优路径求解(其中包含MATLAB的一些关键语句说明和Floyd,Dijkstra,Euler算法)摘要车辆路径问题可以分为以点为服务和以边为服务两种&#xff0c;洒水车问题是以边为服务的一个子问题。作为容量限制弦路径车辆行驶问题(CARP)的一种实际应用&#xff0c;…

地震matlab频域分析,基于matlab的地震数据的分析.doc

基于matlab的地震数据的分析.doc 基于MATLAB的地震数据的分析孙玉柱冯光房桂梅摘要地震波原始数据中存在的干扰信号&#xff0c;会影响震相分析的准确性。为了滤除干扰信号&#xff0c;对地震波原始信号进行了频谱分析&#xff0c;给出了一种基于MATLAB的FIR数字滤波器的优化设…