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. Spring官网阅读(五)BeanDefinition(下)

    上篇文章已经对BeanDefinition做了一系列的介绍,这篇文章我们开始学习BeanDefinition合并的一些知识,完善我们整个BeanDefinition的体系,Spring在创建一个bea ...

  2. .Net Core微服务化ABP之六——处理Authentication

    上篇中我们已经可以实现sso,并且为各个服务集成sso认证.本篇处理权限系统的角色问题,权限系统分两层,第一层为整体系统角色权限,区分app用户.后台用户.网站用户的接口权限,第二层为业务系统权限,对 ...

  3. indexDB出坑指南

    对于入了前端坑的同学,indexDB绝对是需要深入学习的. 本文针对indexDB的难点问题(事务和数据库升级)做了详细的讲解,而对于indexDB的特点和使用方法只简要的介绍了一下.如果你有一些使用 ...

  4. Web_php_unserialize

    0x01 <?php class Demo { private $file = 'index.php'; public function __construct($file) { $this-& ...

  5. 基于Memcached的Nginx服务器集群session共享

    原料:jdk1.8,tomcat7,nginx1.16,memcached-1.2.6,Mem-Tomcat需要的jar包,基于windows7.所有的点击以下链接可下载 链接:https://pan ...

  6. fastadmin后台:在表单操作项添加操作按钮并控制弹出页面的大小

    1.进入对应目录:eg(public/assets/js/backend/conmpany.js) 2.在field:'operate' 中添加buttons 源码: {field: 'operate ...

  7. Redux:异步操作

    最近状态不太好,学习redux的异步操作花的时间比想象的多,这里尽量清晰简要的表述一下在redux中怎么实现异步操作. 先回顾一下同步操作: 我们用redux执行同步的时候,都是先发起一个dispat ...

  8. Power安装linux-BIG ENDIAN mysql编译安装

    一.安装系统,不选择额外的软件 mkvdev -vadapter vhost0 -vdev hdisk2 -dev db_mysql01_sys mkvdev -vadapter vhost0 -vd ...

  9. 必须使用角色管理工具 安装或配置microsoft.net framework 3.5

    windows server 2008安装sql server 2012后报错,要求安装microsoft.net framework 3.5 sp1 但安装时提示,必须使用角色管理工具 安装或配置m ...

  10. Redis-Redis基本类型及使用Java操作

    1 Redis简介     Redis(REmote Dictionary Server)是一个使用ANSI C编写的.开源的.支持网络的.基于内存的.可持久化的键值对存储系统.目前最流行的键值对存储 ...