java方法句柄-----3.方法句柄的实现接口
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.方法句柄的实现接口的更多相关文章
- java方法句柄-----2.方法句柄的获取、变换、特殊方法句柄
目录 1.获取方法句柄 1.1查找构造方法.一般方法和静态方法的方法句柄 1.2 查找类中的特殊方法(类中的私有方法) 1.3 查找类中静态域和一般域 1.4 通过反射API得到的Constructo ...
- java方法句柄-----1.方法句柄类型、调用
目录 方法句柄 1.方法句柄的类型 1.1MethodType类的对象实例的创建 1.1.1 通过指定参数和返回值的类型来创建MethodType.[显式地指定返回值和参数的类型] 1.1.2 通过静 ...
- 【转】Graphics.DrawImage 方法 IntPtr 结构 GDI 句柄 知识收集
Graphics.DrawImage 方法 在指定的位置使用原始物理大小绘制指定的 Image. 命名空间:System.Drawing 程序集:System.Drawing(在 system.dra ...
- java类加载机制及方法调用
类加载机制 概述 类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载(Loading).验证(Verification).准备(Preparation).解析(Resoluti ...
- Java虚拟机栈---本地方法栈
1.Java虚拟机栈(Java Virtual Machine Stacks) 线程私有,它的生命周期与线程相同.描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧(Stack ...
- 使用java泛型设计通用方法
泛型是Java SE 1.5的新特性, 泛型的本质是参数化类型, 也就是说所操作的数据类型被指定为一个参数. 因此我们可以利用泛型和反射来设计一些通用方法. 现在有2张表, 一张user表和一张stu ...
- 获取当前应用的系统路径工具类和java的System.getProperty()方法介绍
java的System.getProperty()方法可以获取的值,如下: 对于Java程序,无论是未打包的还是打包的JAR或WAR文件,有时候都需要获取它运行所在目录信息,如何做到这一点呢? /** ...
- Java实现时间动态显示方法汇总
这篇文章主要介绍了Java实现时间动态显示方法汇总,很实用的功能,需要的朋友可以参考下 本文所述实例可以实现Java在界面上动态的显示时间.具体实现方法汇总如下: 1.方法一 用TimerTask: ...
- 第6章 Java类中的方法
1.如何定义java的方法 什么是方法:方法使用来解决一类问题的代码集合,是一个功能模块在类中定义个方法的方法是: 访问修饰符 返回值类型 方法名(参数列表){ 方法体 } 1.访问修饰符,是限制该方 ...
随机推荐
- Idea中查看一个类的所有资料及其层级关系
在Idea中直接Ctrl + t 查看类的子类是可以看到,但是他没有那种层级顺序! 我们可以在类中点击顶部菜单Navigate -----> Type Hierarchy
- 【Spark】Spark必不可少的多种集群环境搭建方法
目录 Local模式运行环境搭建 小知识 搭建步骤 一.上传压缩包并解压 二.修改Spark配置文件 三.启动验证进入Spark-shell 四.运行Spark自带的测试jar包 standAlone ...
- centos7启动httpd服务失败:Job for httpd.service failed because the control process exited with error code.
centos7启动httpd命令有两个可以用 service httpd start systemctl start httpd.service 如果出现如下报错 Job for httpd.s ...
- 数据结构学习:二叉查找树的概念和C语言实现
什么是二叉查找树? 二叉查找树又叫二叉排序树,缩写为BST,全称Binary Sort Tree或者Binary Search Tree. 以下定义来自百度百科: 二叉排序树或者是一棵空树,或者是具有 ...
- Linux 内核代码风格
文章目录 从编码风格错误开始 快速修改编码风格的工具 scripts/checkpatch.pl scripts/Lindent astyle Linux 内核代码风格 1) 缩进 2) 把长的行和字 ...
- RabbitMQ的发布订阅模式(Publish/Subscribe)
一.发布/订阅(Publish/Subscribe)模式 发布订阅是我们经常会用到的一种模式,生产者生产消息后,所有订阅者都可以收到.RabbitMQ的发布/订阅模型图如下: 1.该模式下生产者并不是 ...
- CodeForces-650B Image Preview 二分+模拟
CodeForces-650B Image Preview 题意 手机里有n张图片,打开相机出现的是第一张,第一张右滑得到第n张,同理第n张左滑得到第1张,翻页耗费a秒,看照片耗费1s,但是照片有横屏 ...
- [c++ IO加速]快速输入输出
自己封装的FastIO类,效率虽有所损失,不过实用性提高很多. 测试,写10000000个整数(86M): printf 2.7s cout 27s FastIO 1s 测试,读10000000个整数 ...
- python 定义一个插入数据(可以插入到每个表中)通用的方法
前提置要:想要写一个方法,这个方法是插入数据到数据表的方法,只需要提供表名称,字段名称,还有插入的值,只要调用这个方法就可以自动帮助你插入数据 以下是不断实践优化出来 原本的插入数据库中的代码应该是这 ...
- HttpServletRequest与HttpServletResponse
一. 简介:每当客户端给Web服务器发送一个http请求,web服务器就会针对每一次请求,分别创建一个用于代表请求的request对象.和代表响应的response对象.request和respons ...