Dúvida sobre Generics... <? super T>

Sendo que Dog extende Animal e [color=red]Integer[/color] não tem nada haver com a hierarquia. Não seria o correto dar problema na chamada testeVoid(lista3); na linha 12, pois a mesma passa um java.lang.Integer?

[code] static void testeVoid(List<? super T> listaIn) {

}

public static void main(String[] args) {
    List<Animal> lista1 = new LinkedList<Animal>(); // Animal é Superclasse
    List<Dog> lista2 = new LinkedList<Dog>(); // Dog é Subclasse de Animal
    List<Integer> lista3 = new LinkedList<Integer>(); // Integer não faz parte da Hierarquia

    testeVoid(lista1); // OK! Animal é um Animal
    testeVoid(lista2); // OK! Dog é um Animal
    testeVoid(lista3); // Não deveria acusar problema aqui? Estou passando um Integer (Não é Animal)
}[/code]

Desde já agradeço a ajuda. :wink:

De fato, o compilador do Eclipse considera isso como um erro, mas o javac não.

Submeta seu programa ao http://bugs.sun.com e pergunte qual é o comportamento correto.

Além disso é interessante postar esse programa em algum fórum do java.net.

    /*
     * Mensagem de erro do Eclipse:
     * Bound mismatch: The generic method testeVoid(List<? super T>) 
     * of type Super is not applicable for the arguments (List<Integer>). 
     * The inferred type Integer is not a valid substitute for the bounded 
     * parameter <T extends Animal>
     * 
     * O javac da Sun não reporta nenhum erro. 
     */

Isso é um bug no compilador realmente. Ocorre porque o extends e o super no mesmo parâmetro de tipo confunde o compilador.

Eu não consegui implementar qualquer coisa que fizesse sentido no método testeVoid e usasse o parâmetro fornecido porque não consigo satisfazer tanto o extends quanto ao super ao mesmo tempo.
T extends Animal diz que T é Animal ou uma subclasse.
? extends T confunde o compilador porque ele não consegue determinar o que é. “Alguma superclasse de alguma subclasse de Animal”

Ou seja se Poodle extends Dog extends Animal extends Object, então pode ser uma lista de Poodle, Dog, Animal ou Object, onde T é Animal, Dog ou Poodle. Mas acho que o compilador ao se confundir assume que é Object, o que faz aceitar o Integer.

Vou alternando meus testes entre o Eclipse e o Java SE.

Obrigado!

Se alguém pudesse me explicar o que significam os parâmetros do método do colega, agradeceria:

static void testeVoid(List<? super T> listaIn) {

}

O que significa <? super T>? E para que serve o operador “?” (interrogação) ali?

[quote=eclipso]Se alguém pudesse me explicar o que significam os parâmetros do método do colega, agradeceria:

static void testeVoid(List<? super T> listaIn) {

}

O que significa <? super T>? E para que serve o operador “?” (interrogação) ali?[/quote]

<? super T> significa alguma superclasse ou superinterface de T.

Tá…Mas pra que serve, genericamente falando, o operador “?” ?

Cara, vou explicar humildemente, porém acredito que eu esteja errado.
Você tem uma superclasse Animal e uma subclasse de Animal, Dog. Se você quiser passar uma List de Animal para uma função e fizer

void funcao(List<Animal> lista)

Significa que você pode passar Dog, certo? Errado. A função espera uma Lista de Animal e não de Dog. Portanto, se você tentar fazer

List<Animal> lista = new ArrayList<Animal>();
funcao(lista);

Funciona, mas se você fizer

List<Dog> lista = new ArrayList<Dog>();
funcao(lista);

Não funciona. Portanto, você deve usar Generics, que é o que vem antes do tipo da função ali no código do colega.

Acho que é isso… me desculpem se eu estiver errado, mas é sábado e não tem muita movimentação no fórum…
Tente dar uma pesquisada sobre generics, você pode aprender muito mais.

Abraço.