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.
Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!
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