From Programming Languages:Principles and Paradigms By Maurizio Gabbrielli、Simone Martini
型変数のバインドされたメカニズムはかなり洗練されており、柔軟性があります。特に、型変数はそれ自体の境界に現れる可能性があります。このケースの1つの例に限定し、より深い議論のために読者に参考文献を紹介します。
クラスが
Comparable
インターフェースを実装している場合、クラスの要素は同等です。ジェネリック型の要素のリストを引数として指定し、このリストの最大要素を返すメソッドを定義したいと思います。このmaxメソッドに与えることができる署名は何ですか?最初の試みは次のとおりです。_public static <T extends Comparable<T>> T max(List<T> list)
_これは、リストの要素が同じタイプの要素と比較可能でなければならないという事実を表しています。ここで、
max
を使用しようとします。オブジェクトを比較できるタイプFoo
があります。_class Foo implements Comparable<Object>{...} List<Foo> cf = ....;
_ここで、
max(cf)
を呼び出します。cf
の各要素(Foo
であるため)は、すべてのオブジェクト、特にすべてのFoo
と同等です。ただし、Foo
は_Comparable<Foo>
_を実装していないため、コンパイラはエラーを通知します。実際には、Foo
がそれ自体のスーパータイプの1つと同等であるだけで十分です。_public static <T extends Comparable<? super T>> T max(List<T> list)
_これで、以前と同じ条件下で、
Foo
は_Comparable<Object>
_を実装するため、Max(cf)
は正しいです。
_? super T
_はT
のスーパータイプを意味すると思います。
Object
はT
のスーパータイプなので、次のmax
の署名は機能しますか?
_ public static <T extends Comparable<Object>>
T max(List<T> list)
_
はいの場合、引用の最後のものの代わりにそれを使用してみませんか?
Comparable
インターフェースを含むexampleです。引用符のメソッドを使用して解決できる一般的な問題とは何ですか?私たちが持っていた場合:
public static <T extends Comparable<Object>>
T max(List<T> list)
それは一緒に働いていただろう
class Foo implements Comparable<Object>{...}
List<Foo> cf = ....;
しかし、
class Bar implements Comparable<Bar>{...}
List<Bar> cf = ....;
彼らの最初のmax
署名は、T
をT
と比較できることを要求します-したがって、List
sはFoo
と比較できるため、Foo
sのObject
では機能しません。 max
署名では、T
をObject
と比較できる必要があります。したがって、List
は別のBar
としか比較できないため、Bar
sのBar
では機能しません。
List<Foo>
とList<Bar>
の両方で機能するには、2番目のmax
バージョンが必要です。 「そのタイプの他のオブジェクトと比較できるもののリストを教えてください。ただし、他のタイプも受け入れる、より広い比較方法がある場合は、それが受け入れられる限り、問題ありません。独自のタイプです。 "。
したがって、Baz implements Comparable<Foo>
のリストは問題外です。これは、Baz
をそれ自体(Baz is not a subclass of
Foo`)と比較できないためです。
基本的に、このメソッドによって解決される一般的な問題は、ジェネリックパラメーターのサブクラス/スーパークラスで動作する可能性があることです。これは、ジェネリックパラメーターとの間でのみアップキャストされるためです。 ? super T
/? extends T
を使用してこれを署名にエンコードし、ジェネリックをさまざまなタイプで使用できるようにします。