プロが教える店舗&オフィスのセキュリティ対策術

Java Gold SE8の問題を解いているのですが、下記について混乱しています。

どなたか、「簡単に考えてここはこうなんだよ」とお分かりになる方がいらっしゃいましたら教えて下さい。

Java Gold SE8問題集(俗に言う黒本)の総仕上げ問題で次のような問題が出ています。

P406 問71
ジェネリック・クラスの宣言として正しいものを選びなさい。(1つ選択)
A.public class Test<? extends Integer> {}
B.public class Test<T implements Comparator> {}
C.public class Test<T, U extends T> {}
D.public class Test<T super String> {}

解答と説明は次の通りです。

P450 答え71 C
ジェネリック・タイプの宣言の型パラメータにおける型変数にワイルドカード「?」を使用することはできません。したがって、選択肢Aは誤りです。また、型変数の上限境界の設定にはインターフェースを指定する場合でもextendsキーワードを使用する必要があるため、選択肢Bも誤りです。選択肢Cは、TとUの2つの型変数が宣言されており、そのうちUの上限境界をTに設定している正しいジェネリック・タイプの宣言です。したがって、選択肢Cは正解です。型変数の上限境界に使用できるのはextendsキーワードであるため、選択肢Dも誤りです。

〜引用ここまで〜

Bがimplementsできないのは分かるのですが、AとDは(個人的感覚として)結構頻繁に見る型だったので、なぜAとDがダメなのかと言うのが整理できないでいます。

Aがダメなの理由としては、そのクラスの内部の記述をする際、特定の型Tが宣言されているならばTでコーディングできるので良いのだが、ワイルドカードの?で宣言されても、?はクラス内部のコーディングで使用できないから、と言うように理解しました。

それでは今まで見てきたList<? extends T>などの記述はどこで使うのか? 
また、List<? super T>なども見てきましたが、public class Test<T super String> はなぜいけないのか。

恐らくはジェネリクスに対する理解が中途半端なまま問題集や参考書を読んできてしまったので、上記に整合性が取れないままでいるかと思うのです。

ワイルドカードや下限境界・上限境界などの理解として、「この型を指定した場合は、指定型の継承クラスが扱える」/「この型を指定した場合は、指定型のスーパークラスが扱える」と言う理解まではしているのですが、その「ワイルドカードや下限境界・上限境界」がどこで使用できてどこで使用できないのか、と言う理解が定まりません。

漠然とした内容となってしまい恐縮ですが、どなたかお分かりに為る方がいらっしゃいましたらご教授頂けないでしょうか。

A 回答 (2件)

ジェネリッククラスの「宣言」と「使用」を区別すればよいのでは.

    • good
    • 0
この回答へのお礼

回答ありがとうございます。
細かく具体的に書けば、

1.Classそのものの中身のコーディング時の型指定→使用不可
2.static void doIt(A<? super Y> arg) {}などでのメソッド引数の型指定時→使用可
3.List<? super Integer> = 〜などオブジェクトでの型指定時→使用可

と言う感じでしょうか。

お礼日時:2021/01/06 23:08

例えば変数を宣言する時、「型の実引数」として


List<? extends Number> numlist = ・・・・
とすることは OK。
#用語があっているか不明(^^;

こいつには List<Integer>型のリストと代入互換性がある。
List<Number> numlist = ・・・・
では代入できない。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

No.1で頂いた回答への御礼と併せますと、
Classそのものの中身のコーディングでは使用不可、それ以外では使用できる、と言うところに落ち着きそうですね・・・

お礼日時:2021/01/06 23:14

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!