Java - SAM类型优化



描述Project Lambda状态的工作文档提到了所谓的SAM(单个抽象方法)类型。据我所知,目前的lambda提案不会影响运行时,只会影响编译器,使从lambda表达式到这些类型的自动转换成为可能。

我认为在理想情况下,SAM类型的实例可以在内部由函数指针表示。因此JVM可以避免为这些实例分配内存。

我想知道现代虚拟机是否能够提供这样的优化

@Tamás你可能应该读一下Brian Goetz的邮件列表帖子:

http://mail.openjdk.java.net/pipermail/lambda-dev/2011-August/003877.html

基本上,lambda抽象目前是使用对象实现的。然而,它被设计为允许lambdas的其他实现,这将比类的实例"更小"。

你可以把这种情况想象成类似于自动装箱——整型被装箱为整型,但是有一个"更小"的表示(作为整型)。

目前,lambda必须被封装为SAM类型的实例,因为JVM目前没有办法用任何更小的结构来表示lambda。在未来,可能会有一个新的JVM标准,其中包括"原始函数",它可以将lambdas表示为对象以外的其他东西。

所以,回答你的问题,你上面提出的优化类型可能是可能的,但它可能会出现在java 8之后的"基本函数"上,而不是特定于实现的功能。

将单个方法类转换为函数指针没有什么困难,但是您错过了一件事:lambda表达式不仅仅是函数,它们是闭包。不同之处在于闭包可以捕获外部变量。考虑下面的伪Java示例:

public Adder makeAdder(double startNumber) {
    return #{ int number -> number + startNumber}
}
...
int startNumber = 5; 
Adder add5 = makeAdder(startNumber);
add5.invoke(4);  // ==> 9 

在本例中,由调用makeAdder()生成的lambda函数引用在该lambda之外定义的变量。这就是为什么它被称为"闭包"——它们"封闭"在它们的自由变量上(在这种情况下-在startNumber上)。为了处理这种情况,闭包必须同时保存指向函数的指针和指向其环境的指针。你得到一些数据结构,它有一个方法和至少一个变量。但这不是OOP中对象的定义吗?那么,如果可以将其作为匿名类的实例,创建新类型对象的原因是什么呢?

然而,可以对此类匿名类进行一些其他优化。您提到的工作文档提到了其中的一些,例如,推断和有效地使用final变量(尽管这样做主要是为了允许JVM上的lambdas,而不是优化代码)。生成的匿名类也可以最终完成,大多数jvm已经对最终变量和类进行了很好的优化。

其他改进也可能涉及到环境的引用-有很多选项。

最新更新