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

7 respostas
Carlos.miller

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?

static <T extends Animal> 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)
    }

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

7 Respostas

T

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. 
     */
victorwss

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.

Carlos.miller

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

Obrigado!

E

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?

victorwss

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?

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

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

Andre_Brito

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.

Criado 25 de abril de 2008
Ultima resposta 26 de abr. de 2008
Respostas 7
Participantes 5