Une instance de HashMap<String, String>
correspond à Map<String, ?>
mais pas Map<String, Object>
. Disons que vous voulez écrire une méthode qui accepte les cartes de String
à quoi que ce soit : si vous écrivez
public void foobar(Map<String, Object> ms) {
...
}
vous ne pouvez pas fournir un HashMap<String, String>
. Si vous écrivez
public void foobar(Map<String, ?> ms) {
...
}
ça marche !
Une chose parfois mal comprise dans les génériques de Java est que List<String>
n'est pas un sous-type de List<Object>
. (Mais String[]
est en fait un sous-type de Object[]
C'est l'une des raisons pour lesquelles les génériques et les tableaux ne font pas bon ménage. (les tableaux en Java sont covariants, les generics ne le sont pas, ils sont invariant )).
Un échantillon : Si vous souhaitez écrire une méthode qui accepte List
s de InputStream
et les sous-types de InputStream
vous écrivez
public void foobar(List<? extends InputStream> ms) {
...
}
Au fait : Java efficace de Joshua Bloch est une excellente ressource lorsque vous souhaitez comprendre les choses pas si simples en Java. (Votre question ci-dessus est également très bien couverte dans le livre).