関数内でクラスを宣言し、そのクラスの変数も作成する場合、そのクラスのオブジェクトはスタックまたはヒープにプッシュされますか?内部クラスとのコンテキストで使用する場合、finalキーワードの使用に関して混乱がありますか?変数とクラスオブジェクトの両方がスタックに存在する場合、なぜ変数にfinalという名前を付ける必要があるのでしょうか。
敬具。
関数内でクラスを宣言し、そのクラスの変数も作成する場合、そのクラスのオブジェクトはスタックまたはヒープにプッシュされますか?内部クラスとのコンテキストで使用する場合、finalキーワードの使用に関して混乱がありますか?変数とクラスオブジェクトの両方がスタックに存在する場合、なぜ変数にfinalという名前を付ける必要があるのでしょうか。
敬具。
関数内でクラスを宣言し、そのクラスの変数も作成する場合、そのクラスのオブジェクトはスタックまたはヒープにプッシュされますか?
あなたの用語は正しくありません。おそらくそれが混乱の原因です。
クラスの宣言によって、スペースが割り当てられることはありません...クラスがロードされて初期化されるときに発生するコード、静的などを表すために使用されるスペースの1回限りの割り当ては別として。
Java には関数ではなくメソッドがあります。
メソッド内で変数 (つまり、ローカル変数) を宣言すると、変数自体のスペースがスタックに割り当てられます。(静的変数またはインスタンス変数を宣言すると、スペースはヒープ ノードの一部になります。)
クラスのインスタンス (つまり、オブジェクト) を作成すると、そのインスタンスのスペースがヒープに割り当てられます1。そのインスタンスの参照は、スタック (メソッド内のローカル変数の場合) またはヒープ (静的変数またはインスタンス変数の場合) 上の以前に割り当てられた変数に割り当てられる可能性がありますが、すぐに破棄されることもあります。いずれにせよ、参照用のスペースの割り当ては、インスタンスの作成とは無関係です。
内部クラスとのコンテキストで使用される場合の final キーワードの使用に関して混乱がありますか? 変数とクラス オブジェクトの両方がスタックに存在する場合、なぜ変数に final という名前を付ける必要があるのでしょうか。
final
Java は適切なクロージャをサポートしていないため、これが必要です。内部クラスが外側のスコープ内のローカル変数を参照すると、変数の値が内部クラスに渡され、隠し変数に格納されます。これfinal
により、コンパイラはこれをアプリケーションから効果的に隠すことができます。アプリケーションは変数の内容を変更できないため、変数 2 のコピーが 2 つあることを認識できません。
1 - これは少し単純化しすぎています。興味があれば、「エスケープ分析」を読んでください。
2 - これは、ローカル変数がスタックに格納されるという規則の例外です。この場合、変数のコピーも内部クラス インスタンスのヒープ ノードに格納されます。ただし、これは実装の詳細です...すべてのスタック対ヒープのものと同様です。JVM アーキテクチャがクロージャをサポートするように変更された場合、状況はおそらく異なるでしょう。