Generic - Descobrir instancia da classe

Ae pessoal!

estou em um caso que preciso descobrir o class do meu generic.

exemplo:

public class UserDetailsHibernateDaoImpl<User extends UserDetails>
{	
	public UserDetails loadUserByUsername(String username)
	{
		return (User) this.getHibernateTemplate().get(User.getClass(), username);
	}
}

o caso é ali no User.getClass(), eu preciso saber o class dele, mas não consigo acessar essa propriedade!
esse .getClass() não funciona, alguém sabe uma forma de fazer?

:slight_smile:

vlw

Use

public class UserDetailsHibernateDaoImpl<User extends UserDetails> { public UserDetails loadUserByUsername(String username) { return (User) this.getHibernateTemplate().get(User.class, username); } }

O getClass() é só para objetos

Mais ai que tá !

Nessa classe eu não conheço o User.class, pq ela vai ficar dentro de um .jar
Eu tenho que pegar a instância do objeto que veio pelo generic, para que o hibernate persista;

Meu caso é ± assim, eu tenho um AbstractUser em um .jar

Dai em meu projeto eu crio um User que extende de AbstractUser, e nele eu mapeio os atributos com o hibernate. Se eu mandar o hibernate dar um get passando uma classe genérica ele não aceita, eu tenho que passar o .class do objeto concreto(o que está mapeado) para que funcione;

Qual é o problema de estar dentro de um .jar?

Se sua classe estende AbstractUser e está no classpath, você tem sim o User.class.
Ou você está adicionando o .jar via classloader e carregando o user via reflexão?

Cara acho que não expliquei direito…

o AbstractUser e a a classe que eu mostrei acima estão em um .jar

dai eu extendo na minha aplicação o AbstractUser em User.

ou seja, as classes que estão no .jar não conhecem o User…

me fiz claro?

Entendi. Tinha ficado meio obscuro saber quem estende quem.

Creio que nesse caso não tenha jeito mesmo.

ENTÃO NO USO DE GENERICS USAMOS NORMALMENTE A LETRA “T” QUE DIZ QUE PODERÁ SER QQ CLASSE. QUANDO VC DIZ QUE SEU GENERIC VAI RECEBER UM USER NÃO TEM SENTIDO ALGUM. SE VC JÁ SABE QUE É UM USER QUE VAI CHEGAR ENTÃO NÃO PRECISA DO GENERICS…

ESTOU CERTO ?!?!?!?

Os generics só existem em tempo de compilação. Na hora que o .class é gerado, o java faz automaticamente casts, e trabalha com os tipos como se os generics não existissem. Isso e chamado de type erasure. E é muito mala as vezes.

PS: Não poste com letras maiúsculas.

[quote=ViniGodoy]Os generics só existem em tempo de compilação. Na hora que o .class é gerado, o java faz automaticamente casts, e trabalha com os tipos como se os generics não existissem. Isso e chamado de type erasure. E é muito mala as vezes.
PS: Não poste com letras maiúsculas.[/quote]

Algum problema com as letras ??? Não entendi…

Por isso mesmo que não tem necessidade de ele usar generics…ele já sabe q esta vindo um User e os generics se não me engano não possuem informação sobre a classe tipada.

Sim, vários problemas com as letras maiúsculas. É falta de etiqueta, pois isso geralmente é usado para representar gritos ou xingamentos, ou, no mínimo, mostra que você quer chamar mais atenção do que outros usuários. Também torna a leitura mais difícil, o que por si só já é ruim. Por isso que essa é a recomendação geral não só nesse fórum, mas em vários outros, na wiki, etc.

O problema dele é que ele precisa saber qual classe é para chamar o método apropriado no Hibernate. E não é possível fazer T.class ou T.getClass(). Não tem muita escapatória, ele terá que passar a classe como parâmetro.

Implemente assim :

public class UserDetailsHibernateDaoImpl{	

	public <User extends UserDetails> User loadUserByUsername(Class<User> type, String username){
		return type.cast(this.getHibernateTemplate().get(type, username));
	}

}

ou

public class UserDetailsHibernateDaoImpl<User extends UserDetails>{	

        private Class<User> type;
        UserDetailsHibernateDaoImpl(Class<User> type){
             this.type = type;
        }

	public  User loadUserByUsername(String username){
		return type.cast(this.getHibernateTemplate().get(type, username));
	}
}

O problema é que eu estou implementando uma interface, e não consigo mudar a assinatura do método, e não sou eu que faz a instância da classe, quem faz isso é o framework…

eu solucionei de uma forma similar a que o sergio falou, tenho um atributo class declarado.
mas pra funcionar tive que extender outras classes.

Giulliano,

acho que vc não intendeu meu problema…
eu tenho um AbstractUser eu podia muito bem colocar AbstractUser.class, mas dai o problema é que não é ela que está mapeada no banco, quem está mapeada, é a classe que extende ela. E para que o hibernate faça a chamada ao banco eu tenho que ter o .class da classe extendida.

meio confuso explicar essas coisas :lol:

mas ta resolvido :wink:

Vlw pessoal!