Java 8以降、JavaはTail-Call Optimization(TCO)。それについて調査して、私は 理由 を知った:
jdkクラス[...]には、jdkライブラリコードと呼び出しコードの間のスタックフレームのカウントに依存して、誰が呼び出しているかを判別する、セキュリティ上重要なメソッドがいくつかあります。
ただし、JVMに基づくScalaは、Tail-Call Optimizationをサポートしています。 Scalaは、コンパイル時にテール再帰の最適化を行います。なぜできないのかJava =同じアプローチを使用しますか?
PS:最新バージョン(Java 11現在)of JavaにTCOが追加されました。これを共有できることを知っている人がいれば、すばらしいでしょう。
注意
TCOがバックログにあり、優先度が低いことを知っていますが、なぜJava Scalaのようにコンパイル時に変更を加えることができないのかを知りたいです。
ほとんどの命令型言語にはないのと同じ理由で、Javaにはテールコール最適化がありません。命令型ループは言語の優先スタイルであり、プログラマーは末尾再帰を命令型ループに置き換えることができます。 ( ソース )
Java同じアプローチを使用できないのはなぜですか?
どのアプローチが使用されるかは言えませんが、 Project Loomの提案 で説明されています:
コールスタックを操作する機能をJVMに追加することは間違いなく必要であるため、このプロジェクトの目標は、スタックをある程度まで巻き戻し、指定された引数でメソッドを呼び出すことを可能にするさらに軽量の構成を追加することでもあります(基本的に、効率的な末尾呼び出しの一般化)。この機能をunwind-and-invokeまたはUAIと呼びます。このプロジェクトの目標は、自動テールコール最適化をJVMに追加することではありません。
私が聞いた限りでは、FibresとContinuationsが現在優先度が高いように見えるため、テールコールの作業はまだ始まっていません。
私はJavaで末尾再帰を実現する方法についてここで非常に素晴らしいブログ投稿を読みました: Knoldusブログ投稿Java末尾再帰
ただし、ブログのコードはコンパイルされないため、コードを使用して小さなリポジトリを作成しましたが、構文を修正してコンパイルしました。 Github repo with working code
これが誰かに役立つことを願って、Knoldusブログ投稿で提示されたアイデアが非常に興味深いことに気づきました。