从 Java 8 开始,Java不提供尾部呼叫优化(TCO)。 经过研究,我发现reason是
在jdk类中,有许多对安全性敏感的方法,它们依赖于在jdk库代码和调用代码之间对堆栈帧进行计数,以确定谁在调用它们。
但是,基于JVM的 Scala 支持尾叫优化。 Scala在编译时进行尾部递归优化。 Java为什么不能使用相同的方法?
PS::不确定Java的最新版本(截至目前的 Java 11 )是否具有TCO。如果知道的人也可以分享这一点,那就太好了。
注意
我知道TCO处于积压状态,并且优先级较低,但是想知道Java为什么不能像Scala那样在编译时进行更改。
由于大多数命令式语言都没有Java,因此Java没有尾部调用优化。命令式循环是该语言的首选样式,程序员可以用命令式循环代替尾部递归。 (Source)
答案 0 :(得分:5)
为什么Java无法使用相同的方法?
我不能说将使用哪种方法,但是在Project Loom's proposal中对此有更好的解释:
毫无疑问,需要增加对JVM进行调用堆栈处理的功能,因此,本项目的目标也是添加一个更轻量级的结构,该结构允许将堆栈展开到某个点,然后使用以下方法调用方法:给定参数(基本上是有效的尾调用的概括)。我们将其称为展开和调用功能,即UAI。向JVM添加自动尾部调用优化不是该项目的目标。
据我所知,关于尾部呼叫的工作尚未开始,因为“纤维和连续性”似乎是当前的重中之重。
答案 1 :(得分:1)
我在这里阅读了一篇非常不错的博客文章,内容涉及如何在Java中实现尾递归: Knoldus blog post on Java tail recursion
但是,他们博客上的代码无法编译,因此我用他们的代码创建了一个小型存储库,但修复了语法,因此可以编译。 Github repo with working code
希望这对某人有用,我发现Knoldus博客文章中提出的想法非常有趣。