Java 8 lambda表达式身份契约 [英] Java 8 lambda expression identity contract

查看:150
本文介绍了Java 8 lambda表达式身份契约的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

JavaDoc Java 1.8的LambdaMetaFactory 指定lambda捕获可能涉及分配新的函数对象,或者可能返回现有的函数对象,但它没有指定何时何地它可能选择这种或那种方式。



查看 LambdaMetaFactory 的实际实现,另一方面很明显,当且仅当lambda表达式没有捕获任何参数时才会发生。



我想知道的是,这种行为实际上是在某处指定的(在JavaDoc)并且可以依赖?很高兴知道我是否可以依赖lambda表达式的身份是否恒定。

解决方案

基本上没有合同它涵盖了评估lambda表达式所产生的对象的身份。这在JLS第15.27.4节中有所介绍,运行Lambda表达式的时间评估。本节明确地未指定创建与lambda对象重用的确切行为。该部分的基本原理很好地解释了这一点:


这些规则旨在为Java编程语言的实现提供灵活性,其中: / p>


  • 每次评估都不需要分配新对象。


  • 由不同的lambda表达式生成的对象不需要属于不同的类(例如,如果主体是相同的)。


  • 评估所产生的每个对象都需要不属于同一个类(例如,可能会内联捕获的局部变量)。


  • 如果现有实例可用,则无需进行在之前的lambda评估中创建(例如,它可能在封闭类的初始化期间分配)。



您当然可以尝试实施,调用 equals()或使用 == 在lambda对象上,将它们放入到 IdentityHashMaps 等,但由于未指定这些确切的行为,您的程序可能会在不同版本的JDK或不同的实现上运行时更改其行为(即中断) Java SE。



我在下面的评论中读到了这个问题的交换,但我真的没有更多的东西可以提供。也许如果你解释一下你想要做什么,我们可以提出一些建议,以替代在地图中使用lambdas作为键。


The JavaDoc for the LambdaMetaFactory of Java 1.8 specifies that lambda capture "may involve allocation of a new function object, or may return an existing function object", but it doesn't specify when and under what circumstances it might choose one way or the other.

Looking at the actual implementation of the LambdaMetaFactory, on the other hand, it is clear that it happens if and only if the lambda expression captures no parameters.

What I'm wondering is, is this behavior actually specified somewhere (outside of the JavaDoc) and can be relied upon? It would be nice to know whether I can rely on a lambda expression's identity being constant or not.

解决方案

There is essentially no contract that covers the identity of objects that result from evaluating a lambda expression. This is covered in the JLS section 15.27.4, Run-time Evaluation of Lambda Expressions. This section explicitly leaves unspecified the exact behavior of creation vs reuse of lambda objects. The rationale from that section explains this well:

These rules are meant to offer flexibility to implementations of the Java programming language, in that:

  • A new object need not be allocated on every evaluation.

  • Objects produced by different lambda expressions need not belong to different classes (if the bodies are identical, for example).

  • Every object produced by evaluation need not belong to the same class (captured local variables might be inlined, for example).

  • If an "existing instance" is available, it need not have been created at a previous lambda evaluation (it might have been allocated during the enclosing class's initialization, for example).

You can, of course, experiment with the implementation, call equals() or use == on lambda objects, put them into IdentityHashMaps, etc., but since these exact behaviors are unspecified, your program may change its behavior (i.e., break) when run on different versions of the JDK or on different implementations of Java SE.

I read the exchange in the comments below the question but I don't really have anything more to offer. Perhaps if you explain what you're trying to do, we could come up with some suggestions for alternatives to using lambdas as keys in a map.

这篇关于Java 8 lambda表达式身份契约的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆