1

メソッド ローカルの内部クラスが、final とマークされたものを除いて、囲んでいるメソッド内で宣言された変数を使用できない理由、囲んでいるメソッド内で宣言された変数は、内部クラスのインスタンスが有効なままである間に消滅する可能性があることを知っていますが、この変数/ s は final と宣言されていますか?

4

5 に答える 5

2

その理由は、Java 言語仕様 #8.1.3で指定されているためです。

使用されているが内部クラスで宣言されていないローカル変数、仮パラメーター、または例外パラメーターは、final として宣言する必要があります。

また、(匿名クラスを置き換えるために) Java にクロージャーを導入することを目的とするプロジェクト ラムダ (Java 8) は、ラムダ式内で非最終変数を使用できるようにする効果的な最終の概念を導入することに注意してください。クロージャー内で変更しないでください。

于 2012-08-10T14:56:14.173 に答える
1

今、最初に私は光を当てたいと思います

最終的なローカル変数はスタックではなくヒープに保存されますか?

説明: SO を調査した結果、すべてのローカル変数 ( final または not ) がスタックに格納され、メソッドの実行が終了すると範囲外になることがわかりました。

ただし、最終変数についてJVMは、開始後に変更されないため、これらを定数として使用します。そして、内部クラスがそれらにアクセスしようとすると、コンパイラはその変数のコピーをヒープ に作成し、内部クラス内に合成フィールドを作成します。クラスには独自のコピーがあります。合成フィールドソースコードには実際には存在しないファイルですが、コンパイラはそれらのフィールドをいくつかの内部クラスに作成して、それらのフィールドにアクセスできるようにします。簡単な単語の隠しフィールドで。

したがって、最終変数もスタックに格納されますが、内部クラスがヒープに格納した変数をコピーします。

メソッドのローカル変数はスタック上に存在し、メソッドの存続期間中のみ存在します。ローカル変数のスコープは、変数が宣言されているメソッドに限定されていることは既にわかっています。メソッドが終了すると、スタック フレームは吹き飛ばされ、変数は履歴になります。ただし、メソッドが完了した後でも、その内部で作成された内部クラス オブジェクトは、たとえば、そのオブジェクトへの参照が他のコードに渡され、インスタンス変数に格納された場合、ヒープ上に残っている可能性があります。メソッド ローカル内部クラス オブジェクトが生きている限り、ローカル変数が生きているとは限らないため、内部クラス オブジェクトはそれらを使用できません。ローカル変数が final とマークされていない限り。また、合成フィールドのように残すことができるため、変数を final にすることは有益です。

于 2016-02-29T19:28:32.173 に答える
1

その理由は [ 実はJava final ローカル変数はどこに保存されているのですか?からの結論です。] :final variables are copied by the compiler into a hidden member variable of the inner class that references it. This way, they are guaranteed to not change after the copy has been made.

また、ヒープ上にあるメソッドローカル内部クラスとスタック上にある変数のスコープが異なります。ただし、ローカル変数が final でマークされている場合は、ヒープに格納されます。

于 2012-08-10T14:45:28.570 に答える
1

変数が final の場合、コピーが内部クラスに配置されます。つまり、まだ変数にアクセスできませんが、使用できるコピーがあります。

リフレクションまたはデバッガーを使用すると、これらのコピーを表示できます。

于 2012-08-10T14:52:14.783 に答える
0

Final は、その変数への参照が失われないことを保証します。宣言されたコンテキストで引き続き使用する可能性があるため、内部クラスが参照を破棄したり失ったりすることは望ましくありません。

于 2012-08-10T14:45:09.810 に答える