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:
- Bulky syntax
- Confusion surrounding the meaning of names and
this
- Inflexible class-loading and instance-creation semantics
- Inability to capture non-final local variables
- 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
但基本上
- 匿名 classes 需要为每个文件(MyClass$1 等)制作新的 class 文件。这个额外的 class 必须加载。 Lambda 不会生成新的 class 文件,它们的字节码是在运行时动态创建的。
- Java 的未来版本可能会在幕后使 Lambda 变得不同。通过在运行时生成 lambda 字节码,未来的版本可以安全地改变 Lambda 的创建方式而不会破坏任何东西
关于(3)我还想补充一点。 "Instance-creation" 可能指的是当您创建匿名 class (new ...
) 的实例时,就像您创建任何 class 的实例时一样,您可以保证得到一个新的对象。所以引用保证比较不相等 !=
对任何其他对象的引用。
另一方面,对于 lambda,无法保证 运行 两次 lambda 表达式会计算出两个不同的对象。特别是,如果 lambda 不捕获任何变量,则 lambda 的所有实例在功能上都是相同的。在这种情况下,它可以只静态分配一个对象并在程序运行期间使用它。分配大量对象并不便宜,所以在可以避免创建更多对象的情况下,它使程序更高效。
我再次阅读了关于 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:
- Bulky syntax
- Confusion surrounding the meaning of names and
this
- Inflexible class-loading and instance-creation semantics
- Inability to capture non-final local variables
- 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
但基本上
- 匿名 classes 需要为每个文件(MyClass$1 等)制作新的 class 文件。这个额外的 class 必须加载。 Lambda 不会生成新的 class 文件,它们的字节码是在运行时动态创建的。
- Java 的未来版本可能会在幕后使 Lambda 变得不同。通过在运行时生成 lambda 字节码,未来的版本可以安全地改变 Lambda 的创建方式而不会破坏任何东西
关于(3)我还想补充一点。 "Instance-creation" 可能指的是当您创建匿名 class (new ...
) 的实例时,就像您创建任何 class 的实例时一样,您可以保证得到一个新的对象。所以引用保证比较不相等 !=
对任何其他对象的引用。
另一方面,对于 lambda,无法保证 运行 两次 lambda 表达式会计算出两个不同的对象。特别是,如果 lambda 不捕获任何变量,则 lambda 的所有实例在功能上都是相同的。在这种情况下,它可以只静态分配一个对象并在程序运行期间使用它。分配大量对象并不便宜,所以在可以避免创建更多对象的情况下,它使程序更高效。