javaのラムダこの参照
質問
無名クラスをラムダ式に変換したい。しかし、この無名クラスは
this
というキーワードを使っています。
例えば、こんなシンプルなObserver/Observableパターンを書いてみました。
import java.util.ArrayList;
import java.util.Collection;
public static class Observable {
private final Collection<Observer> notifiables = new ArrayList<>();
public Observable() { }
public void addObserver(Observer notifiable) { notifiables.add(notifiable); }
public void removeObserver(Observer notifiable) { notifiables.add(notifiable); }
public void change() {
notifiables.forEach(notifiable -> notifiable.changed(this));
}
}
public interface Observer {
void changed(Observable notifier);
}
と、匿名クラス(thisキーワードを使用)を使ったサンプルコードです。
public class Main {
public static void main(String[] args) {
Observable observable = new Observable();
observable.addObserver(new Observer() {
@Override
public void changed(Observable notifier) {
notifier.removeObserver(this);
}
});
observable.change();
}
}
となっていますが、ラムダ式に変換すると
public class Main {
public static void main(String[] args) {
Observable observable = new Observable();
observable.addObserver(notifier -> { notifier.removeObserver(this); });
observable.change();
}
}
こんなコンパイルエラーが出ます。
Cannot use this in a static context and in a non `static` context
public class Main {
public void main(String[] args) {
method();
}
private void method() {
Observable observable = new Observable();
observable.addObserver(notifier -> {
notifier.removeObserver(this);
});
observable.change();
}
}
コンパイルエラーは
The method removeObserver(Main.Observer) in the type Main.Observable is not applicable for the arguments (Main)
でラムダオブジェクトを参照する方法はありますか?
this
?
どのように解決するのですか?
を参照することはできません。
this
をラムダ式で参照することはできません。のセマンティックは
this
は、ラムダ式内から周囲のクラスのインスタンスのみを参照するように変更されました。ラムダ式の
this
をラムダ内部から参照する方法はありません。
問題なのは
this
の中で
main()
というメソッドがあります。main メソッドは静的であり、また
this
.
を使用する場合
this
を使うと、内部クラスのインスタンスを参照することになります。
ラムダ式は内部クラスではありません。
this
はラムダ式のインスタンスを参照しているわけではありません。ラムダ式を定義したクラスのインスタンスを参照しているのです。あなたの場合、それはMainのインスタンスになります。しかし、静的メソッドの中なので、インスタンスは存在しない。
これが、2つ目のコンパイルエラーの内容です。あなたはMainのインスタンスをメソッドに渡しました。しかし、あなたのメソッドの署名はObserverのインスタンスを必要とします。
更新してください。
この Java言語仕様15.27.2には :
無名クラス宣言に現れるコードとは異なり、ラムダ本体に現れる名前、thisやsuperキーワードの意味や、参照される宣言のアクセス性は周囲のコンテキストと同じです(ただし、ラムダパラメータは新しい名前を導入します)。
の透明性は この (明示的、暗黙的の両方)をラムダ式の本体で透明化すること、つまり周囲のコンテキストと同じように扱うことで、実装の柔軟性を高め、本体内の非限定名の意味がオーバーロードの解決に依存するのを防ぎます。
実際問題として、ラムダ式が自分自身について話す必要があるのは珍しいことです (自分自身を再帰的に呼び出すか、他のメソッドを呼び出すか)。 this, toString() ). ラムダ式が自分自身を参照する必要がある場合(例えば この のように)自分自身を参照する必要がある場合は、代わりにメソッド参照または無名の内部クラスを使用する必要があります。
関連
-
StringBuilderが投げるArrayIndexOutOfBoundsExceptionの探索
-
Zipファイルの圧縮・解凍にantを使用する
-
[解決済み] JavaでInputStreamを読み込んでStringに変換するにはどうすればよいですか?
-
[解決済み] JavaでNullPointerExceptionを回避する方法
-
[解決済み] JavaにおけるHashMapとHashtableの違いは何ですか?
-
[解決済み] Java Mapの各エントリを効率的に反復処理するには?
-
[解決済み] Javaでメモリーリークを発生させるにはどうしたらいいですか?
-
[解決済み] JavaでArrayListではなくLinkedListを使用するのはいつですか?
-
[解決済み] JavaでStringをintに変換するにはどうしたらいいですか?
-
[解決済み】C++11のラムダ式って何?
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
NullPointerException - java.lang.
-
Eclipse の問題 アクセス制限。タイプ 'jfxrt' はAPI解決されていません。
-
メモ帳でJavaプログラムをコンパイルして実行すると、Could not find or load main class ...というエラーが表示される。解決方法
-
Jsoup-Crawlingの動作
-
FindBugの使用概要
-
X11 DISPLAY変数が設定されていない」問題の解決方法
-
API の戻り値を処理するために ResponseEntity を使用する
-
Junitのユニットテストエラー
-
switch case文のcaseの後の列挙定数は列挙型なし
-
[解決済み] ラムダ式はコードの行数を節約する以外に使い道があるのか?