Generics duvida

9 respostas
LPJava

ae pessoal lendo o livro da kathy cap 7, nao conseguir entender a ideia de generics… muito completo… alguem pode me ajudar em entender sua essencia… e tem diferente em usar e usar … a questao do uso do coringa <?> aff… peguei o livro deitel… ta me clareando…amis com muita duvida… a kathy confude o generics com array depois com polimorfismo q respectivamente fala de herança… quem puder me ajudar fico agradecido mesmo… generics ta me deixando em depressao…qdo li sobre o assunto… acho que nem “olá mundo” eu nao sei mais fazer… :frowning:

9 Respostas

J

O principal objetivo de Generics Types é conceder uma forte segurança em relação aos tipos em tempo de compilação.

Por exemplo:

List list = new ArrayList();  
list.add(new String("Olá"));   //Ok
list.add(new Double(12.5));  //Ok
list.add(new Date());           //Ok

Se vc observar o código acima, verá que não tem como garanti qual tipo de objeto está sendo adicionado à List em tempo de compilação. Mas com generics vc pode fazer isso.

Por exemplo:

List<String> list = new ArrayList<String>();
list.add(new String("Olá"));   //Ok
list.add(new Double(12.5));  //Erro em tempo de compilação
list.add(new Date());           //Erro em tempo de compilação

No caso acima a List não aceita elementos do tipo Double, Date ou qualquer outro tipo que não seja subtipo do tipo String.

Lembre-se:

Ao declarar uma interface ou classe genérica da seguinte forma:

public interface List<E>{ public void add(E e){"implementação"} public E get(int index){"implementação"} ... }

e depois quando vc a utiliza

List<String> list = new ArrayList<String>;

Na interface ou classe os E’s serão substituídos por String’s

public interface List{ public void add(String e){"implementação"} public String get(int index){"implementação"} ... }

O caso do e o é somente uma convenção. O significa ELEMENTO e é usado na declaração de Coleções genéricas e o significa TIPO e é usado em declaração de Classes genéricas que não são Coleções.

O <?> é usado para declarar variáveis locais ou atributos. Quando vc declara um atributo da seguinte forma:

List<?> list;

Você tá dizendo que esse atributo aceitará qualquer referência do tipo List<“qualquer classe que herde de Object”>. Por exemplo:

List<?> list1 = new ArrayList<String>();
List<?> list2 = new ArrayList<Date>();
List<?> list3 = new ArrayList<Double>();

Mas quando vc realiza uma declaração desse tipo:

List<?>;

é o mesmo q declarar desta maneira:

List<? extends Object>;

ps: Vc pode substituir o Object por qualquer outra classe ou interface, mas isso mudará a semântica da questão.

Ao utilizar essa declaração (seja com extends ou sem), vc não poderá modificar a referência de nenhum modo.

Qualquer dúvida post aew!!
Espero ter ajudado!!
Flw aew e t+!!

LPJava

entao seria para garantir um valor passado para um argumento de uma lista? ou conjuto?
nao entendi paenas o final qdo vc fala:

"Ao utilizar essa declaração (seja com extends ou sem), vc não poderá modificar a referência de nenhum modo.
"

:frowning:

J

entao seria para garantir um valor passado para um argumento de uma lista? ou conjuto?

Sim. Mas entenda!! Você verá que Generics é muito usado em coleções, mas ele não está limitado a isso somente!! Dependo do problema, vc poderá criar classes utilizando Generics para facilitar sua vida no futuro!! Na certificação eles cobram na maioria dos casos em nível de Collections.

nao entendi apenas o final qdo vc fala:

"Ao utilizar essa declaração (seja com extends ou sem), vc não poderá modificar a referência de nenhum modo.
"

Tudo bem!!

Exemplo:

public void add(List<?> list, Object obj){ list.add(obj); //Não compila!! }

O código acima mostra um método chamado add, que possui 2 parâmetros, sendo um do tipo List<?> e outro do tipo Object. A declaração genérica List<?> como nós vimos anteriormente é igual à List<? extends Object> e esse tipo de declaração possui uma peculiaridade que seria não permitir a modificação do objeto list no nosso caso. Mas como nós estamos vendo, o método está tentando adicionar um Object à List e isso não é permitido!!

Espero ter ajudado!!
Flw aew e t+!!

LPJava

humse usar o <? extends…>

nao posso alterar o estado do objeto seria isso?

J

Exatamente!! Vc não poderá modificá-lo!! Aew existe um outro recurso, que seria o <? super Classe/Interface>. Por exemplo:

public void add(List<? super String> list, Object obj){ list.add(obj); //Agora funciona!! }

Nesse caso, quando vc declara o List com o <? super String>, vc tá dizendo que ali você pode receber qualquer objeto do tipo List, ou seja, List ou List.

Espero ter ajudado!!
Flw aew e t+!!

LPJava

hum saquei valeu!!! pela ajuda ai!!

P

Galera, desculpe desenterrar esse tópico q já é meio antigo, mas caiu como uma luva pra mim.

Estou implementando uma classe abstrata para e tem um método que deve retornar o tipo da classe genérica passa, mas não consigo fazer isso. E também não consigo passar para um método a classe genérica. Como eu poderia fazer isso?
As partes acima me ajudaram pra caramba, aguardo ai quem poder e também, se vc poder dar uma breve explicação ao colocar a idéia de correção, agradeço mermo... só o filé!

Meu método da classe abstrata:

public abstract class Abstrata<T> {

    protected <T> load(Object<T> obj, Long id) {
        T classe = null;
        try {
            EntityManager em = getEntityManager();
            em.getTransaction().begin();
            
            classe = em.find(T.class , id);
            
            em.getTransaction().commit();
            em.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            factory.close();
        }
        
        return classe;
    }

}

vlw ai, desde já..

M

Acho que o que voce quer é:

public abstract class Abstrata<T> {

	private Class<T> entityClass;
	
	public Abstrata(Class<T> ec){
		entityClass = ec
	}

    protected T load(T obj, Long id) {
        T classe = null;
        try {
            EntityManager em = getEntityManager();
            em.getTransaction().begin();
            
            classe = em.find(entityClass , id);
            
            em.getTransaction().commit();
            em.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            factory.close();
        }
        
        return classe;
    }

}

Voce confundiu um pouco a sintaxe.
Tambem nao pode ler o class de um generics por causa de um conceito chamado de Type Erasure. Por isso eu peguei o class no construtor.

Espero que ajude.

P

Caro Marcos…

Era isso mesmo… só me faltava entender a idéia do generics no retorno, agora eu sei. hehehe

Vlw ai a dica e a ajuda.

Abços…

Criado 7 de janeiro de 2007
Ultima resposta 24 de ago. de 2007
Respostas 9
Participantes 4