なぜこれがそんなに紛らわしいのか分かりません。これは、IMOという2つの理由で説明できます。
これが何を意味するのか、そしてそのJLS
周りの言葉が何であるのかを理解させてください。しかし、本質的にこれらはジェネリックのようなものです:
static class Me<T> {
T t...
}
T
ここのタイプは何ですか?まあ、それは異なります。もしあなたがそうするなら :
Me<Integer> me = new Me<>(); // it's Integer
Me<String> m2 = new Me<>(); // it's String
ポリ式は、使用される場所のコンテキストに依存すると言われています。ラムダ式は同じです。ここでラムダ式を分離してみましょう:
(String str) -> str.length() <= 5
あなたがそれを見るとき、これは何ですか?まあそれはPredicate<String>
?しかし、AかもしれませんFunction<String, Boolean>
か?またはかもしれませんMyTransformer<String, Boolean>
、ここで:
interface MyTransformer<String, Boolean> {
Boolean transform(String in){
// do something here with "in"
}
}
選択肢は無限です。
- 理論的に
.negate()
は、直接呼び出すこともできます。
上記の10_000マイルから、あなたは正しいです。あなたはそれstr -> str.length() <= 5
を、removeIf
だけを受け入れるメソッドに提供していPredicate
ます。これ以上removeIf
メソッドはないので、コンパイラーはそれを指定したときに「正しいことを行う」ことができるはずです(str -> str.length() <= 5).negate()
。
では、なぜこれが機能しないのですか?コメントから始めましょう:
negate()の呼び出しでさらに多くのコンテキストが提供され、明示的なキャストの必要性がさらに低下するのではないですか
これが主な問題の始まりであるようjavac
です。これは単に動作する方法ではありません。全体をとることはできません。str -> str.length() <= 5).negate()
これはPredicate<String>
(それをの引数として使用しているためremoveIf
)であることを伝えてから、パーツをさらに分解して、.negate()
それがaかどうかを確認しPredicate<String>
ます。javac
逆に振る舞うので、呼び出すことが合法かどうかを判断できるように、ターゲットを知る必要がnegate
あります。
また、一般的に、ポリ式と式を明確に区別する必要があります。str -> str.length() <= 5).negate()
は式、str -> str.length() <= 5
はポリ式です。
物事が別様に行われ、これが可能である言語が、javac
単にそのタイプではない場合があります。
Predicate<String> predicate = str -> str.length() <= 5; names.removeIf(predicate.negate()); names.removeIf(predicate);