私はそれをテストしましたが、割り当て自体がコンパイルされました。どのような変更が実際にpredicate.test()
に電話できるかどうかです。
説明を省略してプレースホルダGenericClass<T>
を使用して説明します。型引数の場合、Foo
はBar
となり、Bar
はBaz
に拡張されます。
は拡張: あなたがGenericClass<? extends Bar>
を宣言するときに、あなたが言っている「私はそのジェネリック型引数が実際にあるかわからないが、それはBar
のサブクラスです。」実際のインスタンスは常に非ワイルドカード型の引数を持ちますが、コードのこの部分では、その値が何であるか分かりません。次に、メソッド呼び出しの意味を考えてみましょう。
あなたは何を実際に持っていることはGenericClass<Foo>
かGenericClass<Bar>
のいずれかであることを知っています。 T
を返すメソッドを考えてみましょう。前者の場合、戻り値の型はFoo
です。後者では、Bar
です。いずれにせよ、それはBar
のサブタイプであり、Bar
変数に割り当てるのが安全です。
はT
パラメータを持つメソッドを考えてみましょう。 GenericClass<Foo>
の場合は、Bar
を渡すとエラーとなります。Bar
はFoo
のサブタイプではありません。
したがって、上限を使用すると、汎用の戻り値を使用できますが、汎用のメソッドのパラメータは使用できません。
スーパー:あなたはGenericClass<? super Bar>
を宣言するときに 、あなたは「私はそのジェネリック型引数が実際にあるかわからないが、それはBar
のスーパークラスです。」と言っています次に、メソッド呼び出しの意味を考えてみましょう。
あなたが実際に持っていることは、GenericClass<Bar>
またはGenericClass<Baz>
です。 T
を返すメソッドを考えてみましょう。前者の場合は、Bar
を返します。後者では、Baz
。 Baz
が返された場合、その値をBar
変数に代入するとエラーになります。あなたはそれがどれなのかわからないので、安全に何もここで取ることはできません。
はT
パラメータを持つメソッドを考えてみましょう。 GenericClass<Bar>
の場合は、Bar
を渡しても問題ありません。 GenericClass<Baz>
の場合、Bar
はBaz
のサブタイプであるため、Bar
を渡すことはまだ有効です。
したがって、下限を使用すると、汎用メソッドパラメータを使用できますが、汎用戻り値は使用できません。要約すると
:<? extends T>
あなたは、一般的な戻り値ではなくパラメータを使用できることを意味します。 <? super T>
は、汎用パラメータを使用できますが、戻り値は使用できないことを意味します。 Predicate.test()
には汎用パラメータがあるため、super
が必要です。
もう1つ考えるべきこと:ワイルドカードで述べた境界は、オブジェクトの実際の型引数についてです。それらのタイプの結果はで使用すると反対です。上限ワイルドカード(extends
)は、戻り値を割り当てることができる変数の型の下限です。下限ワイルドカード(super
)は、パラメータとして渡すことができるタイプの上限です。 String
の下限ではString
のサブクラスしか受け入れないため、predicate.test(new Object())
はコンパイルされません。
'extend'もコンパイルします。 - 述語<?この述語に 'String'を与えることはできません:)また、my [article](http://bayou.io/draft/)も参照してください。ワイルドカード – ZhongYu
http://stackoverflow.com/questions/33085151/bad-return-type-in-lambda-expression/33085893#33085893 – ZhongYu
'述語のCapturing_Wildcards.html)<? super String>は 'Object'を渡すことはできません(そしてそうしようとするとコンパイルエラーが発生します)。署名 '述語<?スーパーストリング>は '述語