これを考えると:
class MyClass {
static class A {
public boolean property() {
return Math.random() < 0.5;
}
}
static List<A> filterLambda(List<A> list) {
return list.stream().filter(a -> a.property()).collect(Collectors.toList());
}
static List<A> filterMethodCall(List<A> list) {
return list.stream().filter(A::property).collect(Collectors.toList());
}
}
PD:私は質問がに似ている知っている、この1が、私はそれが正しく扱われていないと思います。
これは、BrettOkenによってリンクされたBrianGoetzのドキュメントからの抜粋です。
コンパイラーがラムダ式に遭遇すると、最初にラムダ本体をメソッドに下げます(脱糖します)その引数リストと戻り値の型はラムダ式のものと一致し、場合によってはいくつかの追加の引数があります(字句スコープからキャプチャされた値の場合)。ラムダ式がキャプチャされる時点で、invokedynamic呼び出しサイトを生成します。これは、呼び出されると、ラムダが変換される機能インターフェイスのインスタンスを返します。この呼び出しサイトは、特定のラムダのラムダファクトリと呼ばれます。ラムダファクトリへの動的引数は、字句スコープから取得された値です。ラムダファクトリのブートストラップメソッドは、ラムダメタファクトリと呼ばれるJava言語ランタイムライブラリの標準化されたメソッドです。静的ブートストラップ引数は、コンパイル時にラムダについて既知の情報をキャプチャします(ラムダが変換される関数型インターフェイス、
メソッド参照はラムダ式と同じように扱われますが、ほとんどのメソッド参照を新しいメソッドに脱糖する必要がない点が異なります。参照されるメソッドの定数メソッドハンドルをロードして、それをメタファクトリに渡すだけです。
同じドキュメントから抽出された例:
例として、フィールドminSizeをキャプチャするラムダについて考えてみます。
list.filter(e -> e.getSize() < minSize )
これをインスタンスメソッドとして脱糖し、最初にキャプチャされた引数としてレシーバーを渡します。
list.forEach(INDY((MH(metaFactory), MH(invokeVirtual Predicate.apply),
MH(invokeVirtual B.lambda$1))( this ))));
private boolean lambda$1(Element e) {
return e.getSize() < minSize; }
一方
list.filter(String::isEmpty)
次のように翻訳されます:
list.filter(indy(MH(metaFactory), MH(invokeVirtual Predicate.apply),
MH(invokeVirtual String.isEmpty))()))
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加