Lambda 状态和匿名中的缺陷 类

State of Lambda and Imperfections in Anonymous Classes

我再次阅读了关于 State of Lambda 的 Brian Goetz 文档,其中详细说明了 Java 需要 lambda 表达式的许多原因。

其中一段他写道:

Given the increasing relevance of callbacks and other functional-style idioms, it is important that modeling code as data in Java be as lightweight as possible. In this respect, anonymous inner classes are imperfect for a number of reasons, primarily:

  1. Bulky syntax
  2. Confusion surrounding the meaning of names and this
  3. Inflexible class-loading and instance-creation semantics
  4. Inability to capture non-final local variables
  5. Inability to abstract over control flow

从这个不完善的列表中,我相信我对第 (1)、(2) 和 (4) 项的理解相当好。

但是我不知道(3)和(5)中的问题到底是什么。

有人可以提供任何示例,说明在使用匿名 类 时这两个问题如何成为问题吗?

并不是我从事的所有项目都在 Java 8 上,所以我认为了解这些缺点很重要,最重要的是清楚地看到现在使用 Java 8 lambda 变得更好了.此外,由于 Brian 是 lambda 项目的领导者之一,我认为值得花时间思考一下他的意思,这可能会让我顿悟 :-)

好吧5. Inability to abstract over control flow很简单。

Lambda 非常适合迭代集合中的所有元素。

aCollection.forEach( myLambda)

您必须使用 for 循环或迭代器或类似的旧方法。

for( ....){
   //same code as what's in the lambda
}

这称为内部迭代。我们不仅要告诉集合如何处理集合中的每个元素,还要告诉集合如何获取每个元素。此代码按顺序遍历所有对象。出于性能原因,有时这不是最好的。

Lambda 允许我们进行外部 迭代。我们只告诉集合如何处理每个元素。如何访问每个元素以及以什么顺序访问 Collection 实现,以使用内部实现知识以最有效的方式进行访问。它甚至可能是并行的而不是顺序的。

3. Inflexible class-loading and instance-creation semantics

是关于如何加载和实例化匿名 classes 的较低级别的问题。我将向您指出这篇文章:http://www.infoq.com/articles/Java-8-Lambdas-A-Peek-Under-the-Hood

但基本上

  1. 匿名 classes 需要为每个文件(MyClass$1 等)制作新的 class 文件。这个额外的 class 必须加载。 Lambda 不会生成新的 class 文件,它们的字节码是在运行时动态创建的。
  2. Java 的未来版本可能会在幕后使 Lambda 变得不同。通过在运行时生成 lambda 字节码,未来的版本可以安全地改变 Lambda 的创建方式而不会破坏任何东西

关于(3)我还想补充一点。 "Instance-creation" 可能指的是当您创建匿名 class (new ...) 的实例时,就像您创建任何 class 的实例时一样,您可以保证得到一个新的对象。所以引用保证比较不相等 != 对任何其他对象的引用。

另一方面,对于 lambda,无法保证 运行 两次 lambda 表达式会计算出两个不同的对象。特别是,如果 lambda 不捕获任何变量,则 lambda 的所有实例在功能上都是相同的。在这种情况下,它可以只静态分配一个对象并在程序运行期间使用它。分配大量对象并不便宜,所以在可以避免创建更多对象的情况下,它使程序更高效。