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核心技术与最佳实践》

最新文章

  1. Linux_日志管理介绍(一)
  2. Java——其他容器
  3. Hadoop学习笔记: 全排序
  4. Ramdisk文件系统无法启动
  5. Spring 实践 -IoC
  6. [wordpress]后台自定义菜单字段和使用wordpress color picker
  7. 【百度地图API】北京周边7日游——图标按路线轨迹行动
  8. Android项目实战(三十一):异步下载apk文件并安装(非静默安装)
  9. PAT---完美数列
  10. Springboot security cas整合方案-原理篇
  11. Java面试题——中级(下)
  12. Linux Shell 返回值之 PIPESTATUS
  13. Easyui Tab使用
  14. 我知道的nginx配置
  15. unorder_map 自定义KEY
  16. ActiveX学习笔记二 ActiveX在IE中安全级别问题-实现IObjectSafety接口
  17. python基本运算符、比较运算符、赋值运算符、逻辑运算符
  18. 验证码之SimpleCaptcha (二)
  19. Codeforces820A Mister B and Book Reading 2017-06-28 09:38 67人阅读 评论(0) 收藏
  20. Java_String_Arrays_Character_BigDecimal_Calendar_Math_System

热门文章

  1. 送你一份Redis书单,以后使用缓存的问题不用再问我啦!
  2. 微软关于LINQ的101个例子
  3. 新创建的项目AndroidManifast报App is not indexable by Google Search;
  4. 3D三栅极晶体管(摘抄)
  5. SQLServer用with temptb AS临时表查询或者更新字段,将某个字段赋值成某个字段的值
  6. Gradle 多环境、多渠道打包
  7. 「雕爷学编程」Arduino动手做(30)——光敏二极管模块
  8. vue中使用mixins
  9. 快手4-5月Java岗面经
  10. apache slowloris mod_antiloris for Apache httpd 2.2 / 2.4