ジェネリクス難易度 高無料
次のコードのコンパイル・実行結果として正しいものを選べ。
1 import java.util.*;
2 public class Q2 {
3 public static void print(List<String> list) { System.out.println("String"); }
4 public static void print(List<Integer> list) { System.out.println("Integer"); }
5 public static void main(String[] args) {
6 print(new ArrayList<String>());
7 print(new ArrayList<Integer>());
8 }
9 }
- A
String改行Integerの順で出力される - Bコンパイルエラー(2つの
printが型消去後に同一シグネチャになる) - C実行時に例外がスローされる
- D
Integerのみ出力される
正解・解説・誤答理由・ひっかけを見る▼ open
✓ 正解:B✓Gold監修
解説
ジェネリクスは型消去(type erasure)されるため、
各誤答が違う理由print(List<String>) と print(List<Integer>) は
どちらも実行時には print(List) という同一の消去シグネチャになる。
JLS §8.4.2 により、消去後シグネチャが衝突するオーバーロードは宣言できず、コンパイル時に "name clash" エラーになる。
メソッドのオーバーロードはコンパイル時の静的シグネチャで区別されるが、型パラメータは区別材料にならない。- A2つのメソッドが共存できず宣言段階でコンパイル不成立。実行されない。
- C実行時の問題ではなくコンパイル時エラー。実行に到達しない。
- Dオーバーロード自体が成立しないため、どちらか一方が選ばれることもない。
ひっかけ: 引数の総称型が違うのでオーバーロードできそうに見える。実体は型消去で同一=衝突。
実機確認の答え合わせ
javac Q2.java で 「name clash: print(List<Integer>) and print(List<String>) have the same erasure」 → コンパイル不成立。
✓Gold 保有者による書き下ろし解説・実機で検証済