lambda表达式在每次执行时都会在堆上创建对象吗?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (48)

当我使用Java 8的新语法遍历集合时,如

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

这不等同于下面的“旧语法”片段吗?

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

这是否意味着一个新的匿名者Consumer对象是在堆上创建的?

提问于
用户回答回答于

简单地说,如果一个lambda表达式不捕获值,它将是一个单例,在每次调用时都会被重用。

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

用户回答回答于

当表示lambda的实例被敏感地创建时,取决于lambda体的确切内容。也就是说,关键因素是lambda 从词汇环境中捕获的内容。如果它没有捕获任何从创建到创建的变量状态,则每次输入for-each循环时都不会创建实例。相反,在编译时会生成一个合成方法,lambda使用站点将只接收一个委托给该方法的单例对象。

扫码关注云+社区