evertonsilvagomesjava:
Hum Victor para o compilador entao quando vc passa uma lista ali para List<? super Sub> ele interpreta ela como um "Object" por exemplo?
Não, você não entendeu. O compilador não interpreta assim. Ele interpreta como "tem que ser compatível com List<Sub> AND com List<Super> AND com List<Object>". Se for incompatível com um deles, dá erro. Um Sub é compatível com todos eles, por isso se você usar lista.add(new Sub()), ele vai compilar. No entanto, lista.add(new Super()) não compila, pois não é compatível com Sub e lista.add(new Object()) também não compila.
Pense assim. Ao invés de Sub e Super, vamos usar Cachorro e Animal para ficar mais claro:
class Exemplo {
private Cachorro a1 = new Doberman();
private Animal a2 = new Elefante();
private Object a3 = new Mesa();
public void adiciona1(List<? super Cachorro> lista) {
lista.add(a1); // Compila, pois a1 é do tipo Cachorro.
lista.add(new Cachorro()); // Dá na mesma do que está acima.
}
public void adiciona2(List<? super Cachorro> lista) {
lista.add(a2); // Erro de compilação. Animal pode não ser um Cachorro. Na verdade é um elefante!
lista.add(new Animal()); // Não é um cachorro. É incompatível com o caso List<Cachorro>.
}
public void adiciona3(List<? super Cachorro> lista) {
lista.add(a3); // Erro de compilação. O objeto pode não ser um Cachorro. Na verdade é uma mesa!
lista.add(new Object()); // Não é um cachorro. É incompatível com o caso List<Cachorro>.
}
public void chama() {
List<Cachorro> c = new ArrayList<Cachorro>();
c.add(new Cachorro());
adiciona1(c); // Adiciona 2 cachorros na lista de cachorros, tudo bem!
adiciona2(c); // Se esse método compilasse, acabaríamos com um elefante dentro da lista de cachorros!
adiciona3(c); // Se esse método compilasse, acabaríamos com uma mesa dentro da lista de cachorros!
}
public void chama2() {
List<Animal> c = new ArrayList<Animal>();
c.add(new Elefante());
adiciona1(c); // Adiciona 2 cachorros na lista de animais, tudo bem!
}
public void chama3() {
List<Object> c = new ArrayList<Object>();
c.add(new Geladeira());
adiciona1(c); // Adiciona 2 cachorros na lista de objetos, tudo bem!
}
public void chama4() {
List<Poodle> c = new ArrayList<Poodle>();
c.add(new Poodle());
adiciona1(c); // Erro: Poodle é específico demais.
// Esse método pode adicionar um cachorro que pode não ser poodle.
// De fato, vai adicionar um Doberman e um cachorro genérico!
}
}
Enfim, o compilador olha para o pior caso. Se em adiciona2 você passasse um List<Animal>, não tem problema adicionar um elefante lá. Mas se for um List<Cachorro> tem problema. Como a assinatura do método diz QUE NO PIOR CASO será uma lista de cachorros, então o compilador vê que EXISTE PELO MENOS UM CASO ONDE VAI DAR M..., e por isso ele te dá um erro de compilação.