OCJP - Dúvida método usando Generics

3 respostas
gRoOve

Galera estou com dúvidas em relação ao comportamento de um código envolvendo métodos com Generics, segue meu code:

package scjpgenerics;

import java.util.ArrayList;
import java.util.List;

class Animal {
    public String nome;

    public void emitirSom(){
        System.out.println("Emitir Som");
    }
}

class Cao extends Animal {
    public Cao(String nome){
        this.nome = nome;
    }
    public void emitirSom(){
        System.out.println("Latido!");
    }
}

class Gato extends Animal {
    public Gato(String nome){
        this.nome = nome;
    }
    public void emitirSom(){
        System.out.println("Miado!");
    }
}

class Veterinario {
    public void examinar(List<? super Cao> animais){
        animais.add(new Cao("teste"));
		for (Animal busca : animais) {
            System.out.println(busca.nome + " foi examinado com sucesso.");
        }
    }
}

public class Main {
    public static void main(String[] args) {
        List<Animal> animais = new ArrayList<Animal>();
        
        animais.add(new Cao("dog"));
        animais.add(new Cao("dog1"));

        Veterinario vet = new Veterinario();
        vet.examinar(animais);

    }
}

No método examinar, da classe Veterinario, não é possível percorrer o ArrayList com o enhanced for…o compilador reclama:

incompatible types
required: Animal
found: Object

Gostaria de saber pq tenho que alterar o tipo para Object?
Depois ainda, para ler a variável corretamente tenho que dar casting (Cao)…

3 Respostas

ViniGodoy

Aqui nem sequer compila. Ele diz:
“Type Mismatch: Cannot convert element capture of ? super cao to Animal.”

Isso porque na linha 35, seu for each tenta usar o tipo Animal. Acontece que ? super Cao pode ser qualquer pai de Cao, incluindo Object.
Então, nada te garante que aquela lista terá animais dentro.

gRoOve

Entendido. Vlw Vini.
Outra coisa, a única forma de adicionar novos elementos ao conjunto, utilizando métodos com generics, seria utilizando o “super”? Não tem outra forma né?

ViniGodoy

gRoOve:
Entendido. Vlw Vini.
Outra coisa, a única forma de adicionar novos elementos ao conjunto, utilizando métodos com generics, seria utilizando o “super”? Não tem outra forma né?

Ou com o super, ou sem Wildcards. Afinal, um List sempre poderá guardar seus tipos filhos (Cao e Gato) dentro de si.

public void examinar(List<Animal> animais){  
        animais.add(new Cao("teste"));  
        for (Animal busca : animais) {  
            System.out.println(busca.nome + " foi examinado com sucesso.");  
        }  
    }

Tem que entender que os wildcards referem-se ao tipo de lista que será passada, e não ao tipo de objetos que estão dentro da lista:

  • Um List<? super Animal> é um parâmetro que recebe um List ou um List.
  • Um List<? extends Animal> recebe um List, um List e um List.

Por isso, um List<? super Cao> poderá sempre guardar dentro de si cães. Sabemos que um List guarda cães, tanto quanto um List.
Agora, não podemos assumir que há animais em um List<? super Cao> pois um List não necessariamente só contém animais.

Criado 21 de abril de 2011
Ultima resposta 22 de abr. de 2011
Respostas 3
Participantes 2