Je viens de me rappeler comment ça marche (ça fait un an que j'ai pas fait de java).
En fait, Iterator<Integer> n'est effectivement pas un sous type de Iterator. Et donc effectivement le fait d'appeler f sur i n'est pas vérifiable, et tu auras un warning. En revanche, il existe des types polymorphes Iterator<E> (E est une variable de type), qui te permettent de faire un truc du genre :
bool f(Iterator<E> i) { return i.hasNext(); }
Integer g() {
Iterator<Integer> i = tableau.iterator();
if (f(i)) {
return i.next();
} else {
return (Integer)0;
}
Ca, aux erreurs près, c'est type-checkable.