1.使用方法句柄实现接口

  2.3节介绍的动态代理机制可以在运行时为多个接口动态创建实现类,并拦截通过接口进行的方法调用。方法句柄也具备动态实现一个接口的能力。这是通过java.lang.invoke.MethodHandleProxies类中的静态方法asInterfaceInstance来实现的。不过通过方法句柄来实现接口所受的限制比较多。首先该接口必须是公开的,其次该接口只能包含一个名称唯一的方法。这样限制是因为只有一个方法句柄用来处理方法调用。

  调用asInterfaceInstance方法时需要两个参数,第一个参数是要实现的接口类,第二个参数是处理方法调用逻辑的方法句柄对象。方法的返回值是一个实现了该接口的对象。当调用接口的方法时,这个调用会被代理给方法句柄来完成。方法句柄的返回值作为接口调用的返回值。接口的方法类型与方法句柄的类型必须是兼容的,否则会出现异常。

代码清单2-61是使用方法句柄实现接口的示例。被代理的接口是java.lang.Runnable,其中仅包含一个run方法。实现接口的方法句柄引用的是当前类中的doSomething方法。在调用asInterfaceInstance之后得到的Runnable接口的实现对象被用来创建一个新的线程。该线程运行之后发现doSomething方法会被调用。这是由于当Runnable接口的run方法被调用的时候,方法句柄mh也会被调用。

代码清单2-61 使用方法句柄实现接口的示例

public class UseMethodHandleProxies {
public void doSomething(){
System.out.println("WORK");
} @Test
public void useMethodHandleProxy()throws Throwable{
MethodHandles.Lookup lookup= MethodHandles.lookup();
MethodHandle mh=lookup.findVirtual(UseMethodHandleProxies.class,"doSomething",MethodType.methodType(void.class));
mh=mh.bindTo(this);
Runnable runnable= MethodHandleProxies.asInterfaceInstance(Runnable.class, mh);
new Thread(runnable).start();
}
}

  通过方法句柄来实现接口的优势在于不需要新建额外的Java类,只需要复用已有的方法即可。在上面的示例中,任何已有的不带参数和返回值的方法都可以用来实现Runnable接口。需要注意的是,要求接口所包含的方法的名称唯一,不考虑Object类中的方法。实际的方法个数可能不止一个,可能包含同一方法的不同重载形式。

参考:

  
https://www.baeldung.com/java-method-handles

参考资料:《java程序员修炼之道》、《深入理解java7核心技术与最佳实践》

java方法句柄-----3.方法句柄的实现接口的更多相关文章

  1. java方法句柄-----2.方法句柄的获取、变换、特殊方法句柄

    目录 1.获取方法句柄 1.1查找构造方法.一般方法和静态方法的方法句柄 1.2 查找类中的特殊方法(类中的私有方法) 1.3 查找类中静态域和一般域 1.4 通过反射API得到的Constructo ...

  2. java方法句柄-----1.方法句柄类型、调用

    目录 方法句柄 1.方法句柄的类型 1.1MethodType类的对象实例的创建 1.1.1 通过指定参数和返回值的类型来创建MethodType.[显式地指定返回值和参数的类型] 1.1.2 通过静 ...

  3. 【转】Graphics.DrawImage 方法 IntPtr 结构 GDI 句柄 知识收集

    Graphics.DrawImage 方法 在指定的位置使用原始物理大小绘制指定的 Image. 命名空间:System.Drawing 程序集:System.Drawing(在 system.dra ...

  4. java类加载机制及方法调用

    类加载机制 概述 类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载(Loading).验证(Verification).准备(Preparation).解析(Resoluti ...

  5. Java虚拟机栈---本地方法栈

    1.Java虚拟机栈(Java Virtual Machine Stacks) 线程私有,它的生命周期与线程相同.描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧(Stack ...

  6. 使用java泛型设计通用方法

    泛型是Java SE 1.5的新特性, 泛型的本质是参数化类型, 也就是说所操作的数据类型被指定为一个参数. 因此我们可以利用泛型和反射来设计一些通用方法. 现在有2张表, 一张user表和一张stu ...

  7. 获取当前应用的系统路径工具类和java的System.getProperty()方法介绍

    java的System.getProperty()方法可以获取的值,如下: 对于Java程序,无论是未打包的还是打包的JAR或WAR文件,有时候都需要获取它运行所在目录信息,如何做到这一点呢? /** ...

  8. Java实现时间动态显示方法汇总

    这篇文章主要介绍了Java实现时间动态显示方法汇总,很实用的功能,需要的朋友可以参考下 本文所述实例可以实现Java在界面上动态的显示时间.具体实现方法汇总如下: 1.方法一 用TimerTask: ...

  9. 第6章 Java类中的方法

    1.如何定义java的方法 什么是方法:方法使用来解决一类问题的代码集合,是一个功能模块在类中定义个方法的方法是: 访问修饰符 返回值类型 方法名(参数列表){ 方法体 } 1.访问修饰符,是限制该方 ...

随机推荐

  1. 王颖奇 20171010129《面向对象程序设计(java)》第十三周学习总结

      实验十三  图形界面事件处理技术 实验时间 2018-11-22 1.实验目的与要求 (1) 掌握事件处理的基本原理,理解其用途: (2) 掌握AWT事件模型的工作机制: (3) 掌握事件处理的基 ...

  2. 字节码编程,Javassist篇一《基于javassist的第一个案例helloworld》

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 目录 @ 目录 目录 一.前言 二.开发环境 三.案例目标 四.技术实现 五.测试结果 1. ...

  3. ASP.Net Core中使用Swagger

    我们先简单介绍下什么是Swagger,主要是用来干嘛?? 在Swagger诞生之前,我们通常在开发接口的过程中,需要前后端共同维护一个接口文档,然后大家按照接口文档的规范进行对接.接口文档俨然成了接口 ...

  4. qt-n个数组实现排列组合

    例如:现在有一批鞋子,其中颜色有[‘白色’,‘黑色’,‘灰色’]:大小有[‘40’,‘41’,‘42’],样式有[‘板鞋’,‘运动’,‘休闲’],要求写一个算法,实现[[‘白色’,‘40’,‘板鞋’] ...

  5. spark-2.4.5 安装记录

    参考 https://data-flair.training/blogs/install-apache-spark-multi-node-cluster/ 下载 spark 地址为 http://sp ...

  6. JavaScript 的核心机制——event loop(最易懂版)

    前言 javascript从诞生之日起就是一门单线程的非阻塞的脚本语言. 非阻塞就是当代码需要进行一项异步任务(无法立刻返回结果,需要花一定时间才能返回的任务,如ajax事件)时,主线程会挂起(pen ...

  7. sqli-labs之Page-4

    第五十四关 题目给出了数据库名为challenges. 这一关是依旧字符型注入,但是尝试10次后,会强制更换表名等信息.所以尽量在认真思考后进行尝试 爆表名 ?id=-1' union select ...

  8. Spring全家桶之spring boot(三)

    spring boot集成mybatis 众所周知,spring与springmvc可以无缝集成,而mybatis不是spring旗下的框架,因此需要进行配置,当然,这里的配置也是非常简单的. 1.首 ...

  9. 十分钟看懂AES加密

    十分钟看懂AES加密算法 今天看了Moserware的<A Stick Figure Guide to the Advanced Encryption Standard(AES)>收获了不 ...

  10. Analysis分析器

    一.Analysis简介 场景执行过程中,loadrunner收集执行过程中的数据,存储在扩展名为.lrr的文件中,Analysis分析器打开这个文件,对文件信息进行处理,并生成图和报告. 数据分析不 ...