从Java8开始,java不提供尾部调用优化(tail call optimization,tco)。经过研究,我发现原因是:
在jdk类[…]中,有许多对安全性敏感的方法依赖于计算jdk库代码和调用代码之间的堆栈帧来确定谁在调用它们。
然而,基于jvm的scala支持尾部调用优化。scala在编译时进行尾部递归优化。为什么java不能使用相同的方法?
ps:不确定java的最新版本(现在的Java11)是否有tco。如果有认识的人也能分享,那就太好了。
笔记:
我知道tco处于待办事项中,优先级较低,但我想知道为什么java不能在编译时做出类似于scala的更改。
java没有尾部调用优化,这与大多数命令式语言没有尾部调用优化的原因相同。命令循环是语言的首选样式,程序员可以用命令循环代替尾部递归((来源)
2条答案
按热度按时间gojuced71#
为什么java不能使用相同的方法?
我不能说将使用哪种方法,但在ProjectLoom的提案中有更好的解释:
由于向jvm添加操纵调用堆栈的能力无疑是必需的,因此本项目的目标也是添加一个更轻量级的构造,该构造允许将堆栈展开到某个点,然后使用给定的参数调用方法(基本上是有效尾部调用的泛化)。我们将该特性称为unwind and invoke或uai。本项目的目标不是向jvm添加自动尾部调用优化。
据我所知,关于尾声的工作还没有开始,因为光纤和连续性目前似乎是一个更高的优先级。
pkwftd7m2#
我在这里读了一篇非常好的关于如何在java中实现尾部递归的博文:knoldus关于java尾部递归的博文
但是,他们博客上的代码没有编译,所以我用他们的代码创建了一个小的repo,但是修复了语法,所以可以编译。具有工作代码的github repo
希望这是有用的人,我发现在knoldus博客上提出的想法非常有趣。
编辑:事实上,我后来发现,在博客文章中提出的想法最初是文卡特subramaniam的。他在这里的演讲中讨论了这些问题。