String [] является подклассом Object []
Правильно, см. 4.10.3 Подтипы среди типов массивов :
Если S и T оба являются ссылочными типами, то S []> 1 T [], если S> 1 T.
С String >1 Object
, поэтому String[] >1 Object[]
То есть String[]
является прямым подтипом из Object[]
Объект> 1 Объект []
для этого Object > String[]
; String[]
является (косвенным?) подтипом из Object
Для дженериков такой связи не существует, поэтому List<String> > List<Object>
неверно.
Теперь рассмотрим следующий простой пример:
import java.util.*;
class G {
interface I {
void f();
}
class C implements I {
public void f() {}
}
void allF(List<I> li) {
for (I i : li) { i.f(); }
}
void x(List<C> lc) {
allF(lc);
}
}
Он не компилируется, потому что x
вызывает allF
с List<C>
, который не a List<I>
. Чтобы использовать List<C>
подпись должна слегка измениться:
void allF(List<? extends I> li) {
Теперь он компилируется. Неофициально, li
- это List
из некоторого типа, который расширяет / реализует I. Поэтому List<C>
является , присваиваемым List<? extends I>
. То, что вы можете сделать с таким списком, ограничено. По сути, вы можете читать / получать к нему доступ, но не можете write/modify
.