Por quê no Bean, existe a necessidade de passar o ".class", já que a classe já está sendo passada para o DAO? exemplo: return new DAO(Autor.class).listatodos();
Fico no aguardo.
Por quê no Bean, existe a necessidade de passar o ".class", já que a classe já está sendo passada para o DAO? exemplo: return new DAO(Autor.class).listatodos();
Fico no aguardo.
Como o DAO é genérico você precisa qual classe ele vai trabalhar. Mesmo que ele seja tipado, você não consegue o que foi passado nos diamantes em tempo de execução. Exemplo:
public class Dao<T>
Você não consegue acessar esse T e saber o que foi passado...
Oi Alberto, Sim, porém, por quê ele consegue interceptar apenas a<Classe ? Em todo e qualquer caso, sempre será necessário passar o .class?
Opa Thiago, explicando direitinho (e é uma explicação bem avançadinha e longa). Vamos lá: quando você usa o Generics, seja no DAO, como em qualquer outro lugar, você faz algo como:
class DAO<T> {
public T carrega(Long id) {
// código do método
}
}
E com isso, para instanciar o DAO, você tem que fazer algo como:
DAO<Autor> daoAutor = new DAO<Autor>();
E com essa tipagem na instanciação, agora na hora de usar o DAO, tudo que era T (da nossa tipagem, virou Autor
), ou seja, o retorno do método carrega
que fiz ali, virou Autor
para o caso do meu daoAutor
, certo? Nada de excepcional até aqui.
Então você deve ter pensado: "Porque então eu não poderia fazer isso aqui lá no meu método carrega?"
public T carrega(Long id) {
Class c = T.class;
// código do método
}
Seria o mais lógico e mais simples, certo? Certo. O problema é que T não existe em tempo de execução. T não é uma variável apontando para uma instância do tipo Class
. T nada mais é do que um placeholder
. Ele só guarda o lugar ali para um tipo ser usado na hora da compilação, para garantir que só aceite retornos e parâmetros daquele tipo que foi definido com o T.
De novo, isso só acontece em tempo de compilação. Depois de seu código compilado, ou seja, na hora da execução, esse T não existe mais. Repara então que ele não é uma variável apontando para um objeto do tipo Class
.
Isso é um conceito avançadíssimo do Java chamado Type Erasure (traduzindo livremente aqui, seria algo como "Desaparecimento do tipo").
Por esse motivo, você precisa passar para dentro do seu DAO o que falta, ou seja, a referência para a instância de Class
. Por isso fazemos também o:
class DAO<T> {
private Class<T> classe;
DAO(Class<T> c) {
this.classe = c;
}
public T carrega(Long id) {
// código do método
}
}
Agora, como é garantido pelo construtor que vai haver essa instância de Class
sendo passada, ele existirá lá dentro, pois é justamente o que T não é, uma referência para um objeto do tipo Class
.
Talvez seja meio confuso num primeiro momento, mas veja se consegue captar a ideia e qualquer dúvida que ficar, poste aí para nós te ajudarmos.
Abraços