在本文中,我们将展示一些在 Java 8 中不太为人所懂得的 Lambda 表达式技能及其应用限制。本文的重要的受众是 Java 开辟人员,研究人员以及对象库的编写人员。 这里我们只会应用没有 com.sun 或其他内部类的公共 Java API,如斯代码就可以在不合的 JVM 实现之间进行移植。
结论很简单:
Lambda 表达式作为在 Java 8 中实现匿名办法的一种门路而被惹人,可以在某些场景中作为匿名类的替代筹划。 在字节码的层面上来看,Lambda 表达式被调换成了 invokedynamic 指令。如许的指令曾被用来创建功能接口的实现。 而单个方轨则是应用 Lambda 琅绫擎所定义的代码将调用宛转给实际办法。
例如,我们手头有如下代码:
这段代码被 Java 编译器翻译过来就成了下面如许:
invokedynamic 指令可以用 Java 代码粗略的表示成下面如许:
正如你所看见的,LambdaMetafactory 被用来生成一个调用站点,用目标办法句柄来表示一个工厂办法。这个工厂办法应用了 invokeExact 来返回功能接口的实现。如不雅 Lambda 封装了变量,则 invokeExact 会接收这些变量拿来作为实参。
在 Oracle 的 JRE 8 中,metafactory 会应用 ObjectWeb Asm 来动态地生成 Java 类,其实现了一个功能接口。 如不雅 Lambda 表达式封装了外部变量,生成的类琅绫擎就会有额外的域被添加进来。这种办法类似于 Java 说话中的匿名类 —— 然则有如下差别:
- 匿名类是在编译时由 Java 编译器生成的。
- Lambda 实现的类则是由 JVM 在运行时生成。
metafactory 的若何实现要看是什么 JVM 供给商和版本
在本文的后续内容中,我们将重点介绍 LambdaMetafactory 类及其功能。本文的下一节将假设你已经完全懂得了 metafactory 办法若何工作以及 MethodHandle 是什么。
在本节中,我们将介绍若何应用 lambdas 动态构建日常义务。
检查异常和 Lambdas
如不雅你想应用与 Java Streams 结合应用的 lambdas 内的检查异常的代码呢? 例如,我们须要将字符串列表转换成 URL 列表,如下所示:
URL(String)已经在 throws 处所声清楚明了一个检查的异常,是以它不克不及直接用作 Function 的办法引用。
你说“是的,这里可以应用如许的技能”:
大年夜办法句柄构建 Lambdas
这是一个很挫的做法。原因如下:
- 应用 try-catch 块
- 从新抛出异常
- Java 中类型擦除的应用不足
这个 bug 与 Java 编译器以及在 throws 部分声明泛型异常的才能有关。下面的示例代码演示了这种行动:
这个问题被应用以下方法可以更“合法”的方法解决:
- 检查的异构造由 Java 编程说话的编译器辨认
- throws 部分只是办法的元数据,在 JVM 级别没有语义含义
- 检查和未检查的异常在字节码和 JVM 级别是弗成区分的
解决的办法是只把 Callable.call 的调用封装在不带 throws 部分的办法之中:
快速介绍
这段代码不会被 Java 编译器编译经由过程,因为办法 Callable.call 在其 throws 部分有受检异常。然则我们可以应用动态构造的 lambda 表达式擦除这个部分。
起首,我们要声明一个函数式接口,没有 throws 部分但可以或许委派调用给 Callable.call:
第二步是应用 LambdaMetafactory 创建这个接口的实现,以及委派 SilentInvoker.invoke 的办法调用给办法 Callable.call。如前所述,在字节码的级别上 throws 部分被忽视,是以,办法 SilentInvoker.invoke 可以或许调用办法 Callable.call 而无需声明受检异常:
第三,写一个实用办法,调用 Callable.call 而不声明受检异常:
如今,我们可以毫无顾忌地重写我们的流,应用异常检查:
此代码将成功编译,因为 callUnchecked 没有被声明为须要检查异常。此外,应用单态内联缓存时可以内联式调用此办法,因为在 JVM 中只有一个实现 SilentInvoker 接口的类。
推荐阅读
阿里云发布ECS企业级产品家族 19款实例族涵盖173个应用场景
为知足企业级客户对计算的高标准需求,8月9日,阿里云正式宣布云办事器ECS企业级产品家族,今朝已推出面向173种企业应用处景的19款实例。该系列合适在复杂的企业计算情况下,知足对于高机>>>详细阅读
本文标题:在Java中使用Lambda表达式的技巧
地址:http://www.17bianji.com/lsqh/36645.html
1/2 1