lambda表达式是否在每次执行时都在堆上创建一个对象? [英] Does a lambda expression create an object on the heap every time it's executed?

查看:489
本文介绍了lambda表达式是否在每次执行时都在堆上创建一个对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我使用Java 8的新语法糖迭代一个集合时,例如

When I iterate over a collection using the new syntactic sugar of Java 8, such as

myStream.forEach(item -> {
  // do something useful
});

这不等同于下面的旧语法代码段吗?

Isn't this equivalent to the 'old syntax' snippet below?

myStream.forEach(new Consumer<Item>() {
  @Override
  public void accept(Item item) {
    // do something useful
  }
});

这是否意味着新的匿名消费者对象每次迭代集合时都会在堆上创建?这需要多少堆空间?它有什么性能影响?这是否意味着我在迭代大型多级数据结构时应该使用旧样式for循环?

Does this mean a new anonymous Consumer object is created on the heap every time I iterate over a collection? How much heap space does this take? What performance implications does it have? Does it mean I should rather use the old style for loops when iterating over large multi-level data structures?

推荐答案

它等效但不完全相同。简单地说,如果lambda表达式没有捕获值,它将是在每次调用时重复使用的单例。

It is equivalent but not identical. Simply said, if a lambda expression does not captures values, it will be a singleton that is re-used on every invocation.

行为未完全指定。如何实现JVM给予了很大的自由。目前,Oracle的JVM为每个lambda表达式创建(至少)一个实例(即不在不同的相同表达式之间共享实例),但为所有不捕获值的表达式创建单例。

The behavior is not exactly specified. The JVM is given a big freedom how to implement it. Currently, Oracle’s JVM creates (at least) one instance per lambda expression (i.e. doesn’t share instance between different identical expressions) but creates singleton for all expression which don’t capture values.

您可以阅读此答案了解更多详情。在那里,我不仅给出了更详细的描述,还测试了代码以观察当前的行为。

You may read this answer for more details. There, I not only gave a more detailed description but also testing code to observe the current behavior.

这是由TheJava®语言规范, 15.27.4。 Lambda表达式的运行时评估

This is covered by the The Java® Language Specification, chapter "15.27.4. Run-time Evaluation of Lambda Expressions"

摘要:


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

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.

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

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).

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

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).

这篇关于lambda表达式是否在每次执行时都在堆上创建一个对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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