参照型で囲まれたワイルドカード

Huntro:

私は約2つのトラブルの理解、次のコード持っているPredicateオブジェクトを。最初のものは、より低い有界ワイルドカード、上部境界第2のAを使用します。

Predicate<? super String> p1 = s -> s.startsWith("a"); // why can I call startsWith()?
Predicate<? extends String> p2 = s -> s.startsWith("a");

p1.test("a"); // works
p2.test("a"); // doesn't work (why?)

どのような私が理解していないp1で、なぜそれがクラスからメソッドを呼び出すことが可能であるStringなどの、startsWith()なぜ私は渡すことができますStringにオブジェクトをp1.test()、私はそれを呼び出すことができると期待NumberしてObject、同様のオブジェクト。

以下のようp1に振る舞う私が思ったp2だろうが、しかし、これはそうではありません。私も渡すことはできませんStringにオブジェクトをp2.test()私たちが継承したオブジェクトを期待ので、これは、私には理にかなっていませんString(含むがString)。

私はそれは多分、我々は参照型ではなく、オブジェクト自体のタイプを指定することを、事実とは何かを持っていると思います。しかし、どのようなタイプ、オブジェクトのために使用されていますか?

rgettman:

あなたが呼び出すことが合法startsWithのためにp1もかかわらず、p1下限に入力される? super String型引数があることを推測されているので、Stringラムダ式は、s -> s.startsWith("a");であることが推測されるPredicate<String>タイプの変数に割り当てることが合法です、Predicate<? super String>

このコンパイル:

Predicate<String> ps = s -> s.startsWith("a");
Predicate<? super String> p1 = ps;

これはしていません。

// no "startsWith" on Object
Predicate<? super String> p1 = (Object s) -> s.startsWith("a");

JLSの参照がであるセクション15.27.3、「ラムダ式のタイプ」。

Tは、ワイルドカード・パラメータ、機能インターフェイスタイプであり、ラムダ式が暗黙的に入力され、その後、グランド・ターゲット・タイプは、Tの非ワイルドカードパラメータ(§9.9)である場合

ここでは、地上のターゲット・タイプは、ラムダ式の一種であり、Tここではあなたの下限変数のデータ型であるターゲット・タイプ、です。これは、コンパイラが割り当てを可能にするPredicate<String>ラムダ式の型となる接地ターゲット・タイプとして。

また、予告あなたはにスーパークラスのオブジェクトを渡すことができないことをp1.testあなたが(あなたがすでに持っている)可能性があるため、割り当てられた、Predicate<String>p1とります、String

p1.test(new Object()); // Error: can't pass something higher than String

あなたが渡すことができない理由についてStringp2.testあなたが上位ワイルドカードのような有界持っているとき、? extends Stringタイプパラメータのどちらかである任意のクラスできることを意味し、そのStringまたはサブタイプを。(コンパイラは無視Stringされfinal、ここでの任意のサブクラスが存在することはできないがString。)述語は、p2Aを割り当てることができるPredicate<SillyString>と仮定すると、SillyStringのサブクラスですStringしかし、あなたは渡すことはできませんStringが期待できる方法にSillyString

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=312864&siteId=1