[RESOLVIDO]Dúvida com generics

Pessoal,

estou com essa dúvida de generics, alguém pode me explicar este código:

public class GenericsTest {
  public static void main(String[] args) {
    List<Integer> myList = new ArrayList<Integer>();
    Bar bar = new Bar();
    bar.doInsert(myList);
  }

  private static class Bar {
    public Bar() { }

    private void doInsert(List<? super Integer> myList) { // OK, compila
      myList.add(new Integer(5));
    }
  }
}

Mas trocando abaixo…

    private void doInsert(List<? extends Number> myList) {
      myList.add(new Integer(5)); // Não compila, mas deveria pois Integer extends Number não?
    }

Obrigado.

Relendo a Sierra-Bates,

diferentemente de arrays (ArrayStoreException), a JVM não provê uma exceção específica para generics caso eu tente adicionar algo que não extenda ‘Number’.

Java 6 (Sierra-Bates), págs. 615 a 622.

Ele não deixa você inserir porque a referência “não sabe” em runtime qual o tipo que está dentro da coleção. Tudo o que o método sabe é que é alguma lista com elementos que extendem Number, porém o método “não sabe” qual o tipo exato desta lista. Como você disse, Integer extende Number, porém é correto chamar o método com uma variável do tipo List, List, ou seja, uma lista de qualquer classe que extenda Number. Como pela assinatura do método não tem como ele saber exatamente qual o tipo que foi passado, ele não deixa você incluir, pois embora seja possível incluir um Integer se a lista original era List, seria um erro incluir em qualquer outro caso, como por exemplo se na chamada a lista era List.

Existe uma regra pra isso:

1 - se você quer apenas ler os elementos da coleção parada para o método, utilize <? extends Tipo>
2 - se você quer apenas adicionar ou alterar os elementos da coleção passada para o método, utilize <? super Tipo>
3 - se você quer ler e alterar os elementos da coleção, utilize List, porém neste caso a chamada ao método só funcionará com List