首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java - SAM类型优化

Java - SAM类型优化
EN

Stack Overflow用户
提问于 2011-08-16 23:08:33
回答 2查看 3.3K关注 0票数 7

描述Project Lambda状态的working document提到了所谓的SAM (单一抽象方法)类型。据我所知,目前的lambda提议不会影响运行时,只会影响编译器,因为它可以从lambda表达式自动转换为这些类型。

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

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-08-19 23:46:48

@Tamás你可能应该读一读Brian Goetz的这篇邮件列表:

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

基本上,lambda抽象目前是使用对象实现的。然而,它被设计成允许lambdas的替代实现,这将比类的实例“更小”。

你可以认为这种情况类似于自动装箱-整数被装箱为整数,但有一个“较小”的表示(如整数)。

目前,lambda必须被打包到SAM类型的实例中,b/c JVM目前没有办法用更小的构造来表示lambda。在未来,可能会有一个新的JVM标准,其中包括“原始函数”,它可以将lambda表示为对象以外的其他东西。

因此,回答您的问题,您上面提出的优化类型可能是可能的,但它可能是在Java 8之后的“原语函数”方面的工作,而不是特定于实现的特性。

票数 6
EN

Stack Overflow用户

发布于 2011-08-17 11:26:30

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

代码语言:javascript
复制
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中对象的定义吗?那么,如果可以使其成为匿名类的实例,那么创建新类型的对象的原因是什么呢?

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

其他改进也可能涉及到环境引用--有大量的选择。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7080479

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档