Я думал, что у меня разумное понимание дженериков. Например, я понимаю, почему
private void addString(List<? extends String> list, String s) {
list.add(s); // does not compile
list.add(list.get(0)); // doesn't compile either
}
Не компилируется. Я даже заработал некоторую интернет-карму со знаниями.
Но я бы подумал по тому же аргументу, что это не должно компилироваться:
private void addClassWildcard(List<Class<? extends String>> list, Class<? extends String> c) {
list.add(c);
list.add(list.get(0));
}
И это не должно:
private void addClass(List<Class<? extends String>> list, Class<String> c) {
list.add(c);
list.add(list.get(0));
}
Но оба компилируются. Зачем? Какая разница с примером сверху?
Я хотел бы получить объяснение на общем английском языке, а также указатель на соответствующие части спецификации Java или аналогичные.