[解決済み】別のメソッドで定義された内部クラス内の非終端変数を参照することはできません。
質問
編集しました。 タイマーを数回走らせながら、いくつかの変数の値を変更する必要があります。タイマーを繰り返し実行するたびに、値を更新し続ける必要があります。私は値を更新することを妨げるので、値をfinalに設定することはできませんが、私は以下の最初の質問で説明したようなエラーを得ます。
以前は以下のように書いていました。
別のメソッドで定義された内部クラス内の非終端変数を参照できない"というエラーが発生します。
これは、priceというdoubleとpriceObjectというPriceに対して起こっています。なぜこのような問題が発生するのかわかりますか?なぜfinal宣言が必要なのかがわかりません。また、私が何をしようとしているのかがわかれば、この問題を回避するために何をしなければならないのかがわかります。
public static void main(String args[]) {
int period = 2000;
int delay = 2000;
double lastPrice = 0;
Price priceObject = new Price();
double price = 0;
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
price = priceObject.getNextPrice(lastPrice);
System.out.println();
lastPrice = price;
}
}, delay, period);
}
解決方法は?
Javaはtrueをサポートしていません。
クロージャ
のような無名クラスを使用していても、(
new TimerTask() { ... }
は、一種のクロージャのように見えます。
編集 - 以下のコメントをご覧ください。以下は、KeeperOfTheSoulが指摘するように、正しい説明ではありません。
これがうまくいかない理由です。
変数
lastPrice
とpriceはmain()メソッド内のローカル変数です。匿名クラスで作成したオブジェクトが
main()
メソッドが返されます。
このとき
main()
メソッドが返ると、ローカル変数(例えば
lastPrice
と
price
) はスタックから一掃され、そのため
main()
が返ります。
しかし、匿名クラスオブジェクトはこれらの変数を参照しています。もし匿名クラスオブジェクトがクリーンアップされた後の変数にアクセスしようとしたら、事態はとんでもないことになります。
を作成することで
lastPrice
と
price
final
の場合、それらはもう本当の変数ではなく、定数です。そうすると、コンパイラは単に
lastPrice
と
price
を無名クラスの定数の値で置き換えることで、存在しない変数にアクセスする問題がなくなります(もちろん、コンパイル時に)。
クロージャをサポートしている他のプログラミング言語では、これらの変数を特別に扱い、メソッドの終了時に破壊されないようにして、クロージャがまだ変数にアクセスできるようにしています。
Ankur: これはできますね。
public static void main(String args[]) {
int period = 2000;
int delay = 2000;
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
// Variables as member variables instead of local variables in main()
private double lastPrice = 0;
private Price priceObject = new Price();
private double price = 0;
public void run() {
price = priceObject.getNextPrice(lastPrice);
System.out.println();
lastPrice = price;
}
}, delay, period);
}
関連
-
[解決済み] Java - JTextFieldが空かどうかを確認する
-
[解決済み] JavaでFileFilterを作るには?
-
[解決済み] XX:MaxDirectMemorySizeの既定値
-
[解決済み] ファイルを作成せずに、ファイルが存在するかどうかをチェックする
-
[解決済み] JAVA_OPTIONS、JAVA_TOOL_OPTIONS、JAVA_OPTSの違いについて
-
[解決済み] 午前0時からの時間を秒単位で取得する方法
-
[解決済み] Java の文字列インデックスが範囲外です。0 [閉店]
-
[解決済み] Eclipseでクラスとそれに対応するファイルの名前を変更する方法は?
-
[解決済み] JavaFX 同じパッケージ内なのに「場所が必要です。
-
[解決済み] Javaでdoubleをfloatに変換する
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] maven. -source 1.5ではラムダ式がサポートされていません。
-
[解決済み] javaで部分クラスを実装する方法
-
[解決済み] プロトコルハンドラの初期化に失敗しました。
-
[解決済み] 要素 'beans' の宣言が見つかりません。
-
[解決済み] javax.mail.MessagingException: SMTPホストに接続できませんでしたか?
-
[解決済み] 親から継承したメソッドの可視性を下げることができない [重複]。
-
[解決済み] 1行目2列目でBEGIN_ARRAYを期待したが、BEGIN_OBJECTだった。
-
[解決済み] publicId と systemId の間に空白が必要です。
-
[解決済み] Eclipseでクラスとそれに対応するファイルの名前を変更する方法は?
-
[解決済み] x--やx++はここで何をするのですか?