Descobrir Tipo da classe

Dae pessoal,

Estou com uma dúvida:

To usando Reflaction e precisava descobrir, em tempo de execução, o tipo da classe.

Por exemplo

Class classe = Class.forName(“eventos.TEventoAssociacao”);

a partir do class eu preciso saber que o tipo é TEventoAssociacao, pra usar essa informação
num cast em tempo de execução. Isso é possível??

Valeu.

assim nao dá?


  if(seuObjeto.getClass().getSimpleName().equals(SuaClasseATestar.class.getSimpleName())){

.......
}

melhorando:


Class classe = Class.forName("eventos.TEventoAssociacao");            
            if( classe.getSimpleName().equals(TEventoAssociacao.class.getSimpleName())){
           
            
            }

O meu problema é o seguinte:

Tenho várias classes eventos no meu sistema. Então fiz uma espécie de Factory pra obter esses eventos. Cada evento
possui um tipo (utilizei uma enum) e então passo esse valor para a Factory pra ela me retornar a instancia correta.
Mas como a Factory retorna um Object, preciso retornar também o Type dele para que eu possa fazer um cast em tempo de execução.

Entendeu?

Será que tem como?

Valeu

Voce pode implementar o Metadata.
Caso contrario você pode tb verificar a instancia e fazer o cast.


//...
if(objectOfFactory instance of TEventoAssociacao)
   TEventoAssociacao ev1 = (TEventoAssociacao) objectOfFactory;
else
    if(objectOfFactory instance of TEventoAssociacao2)
       TEventoAssociacao2 ev2 = (TEventoAssociacao2) objectOfFactory;

Att.
Cleison R. Lima

Justamente pra não ter que fazer esses ifs é que eu queria o Type.

Pq senão na classe que eu chamo o Factory, como eu passo a enum TipoEvento, eu já sei de que classe é.
Mas queria que fosse abstrato e que as classes que utilizam o evento não conhecessem os tipos.

Tudo pra que quando eu adicionar uma nova classe Evento, eu não precisasse mudar nada no restante do código.
Mudaria apenas na Factory.

Dado um objeto do tipo java.lang.Class (obtido, por exemplo, a partir de Class.forName):

http://java.sun.com/javase/6/docs/api/java/lang/Class.html

[quote=Jean_Utf]Dae pessoal,

Estou com uma dúvida:

To usando Reflaction e precisava descobrir, em tempo de execução, o tipo da classe.

Por exemplo

Class classe = Class.forName(“eventos.TEventoAssociacao”);

a partir do class eu preciso saber que o tipo é TEventoAssociacao, pra usar essa informação
num cast em tempo de execução. Isso é possível??

Valeu.
[/quote]

Primeiro, java não é Delphi. Livre-se desse prefixo T.

Segundo a sua ideia não faz sentido.
Se vc carrega a classe dinamicamente vc não sabe qual é. Não faz sentido fazer cast.
Agora, se todas as classes que vc carrega dinamicamente foram filhas de uma classe ou interface comum, vc pode retornar um objeto dessa classe. Algo assim:


public static <T extends AInterfaceComum > Class<T> load(String name){

return Class.forName(name).asSubclass(AInterfaceComum.class);

}

Perfeita resposta do Sergio.
Se precisa fazer cast de algo dinamico assim … tem algo errado na sua ideia de implementação.

Uma opção valida é a da interface assim vc pode (“Não que seja certo”), criar um metodo para cada tipo esperado e chamar a funcao dependendo do simple name da class

[quote=sergiotaborda][quote=Jean_Utf]Dae pessoal,

Estou com uma dúvida:

To usando Reflaction e precisava descobrir, em tempo de execução, o tipo da classe.

Por exemplo

Class classe = Class.forName(“eventos.TEventoAssociacao”);

a partir do class eu preciso saber que o tipo é TEventoAssociacao, pra usar essa informação
num cast em tempo de execução. Isso é possível??

Valeu.
[/quote]

Primeiro, java não é Delphi. Livre-se desse prefixo T.

Segundo a sua ideia não faz sentido.
Se vc carrega a classe dinamicamente vc não sabe qual é. Não faz sentido fazer cast.
Agora, se todas as classes que vc carrega dinamicamente foram filhas de uma classe ou interface comum, vc pode retornar um objeto dessa classe. Algo assim:

[code]

public static Class load(String name){

return Class.forName(name).asSubclass(AInterfaceComum.class);

}

[/code][/quote]

O “T” é padrão da empresa para nome de classe. “A”, classe abstrata… “E”, enum… enfim…
Entendi o que vocês falaram… realmente o que eu to tentando me pareceu um pouco de chuncho…
Uma Factory deve retornar objetos comuns a uma interface… o problema é que cada Evento tem seus métodos
distintos.

Pensando aqui, acho que achei uma solução… vou criar uma interface com um método setCampos(List listaCampos)
e passar a lista de campos do Evento. Assim cada objeto conhece a ordem dos campos, e que atributo aquele campo
referencia…
Isso resolve meu problema. =)

O código seria mais ou menos assim antes:


switch(tipoEvento)
{
     Evento1:
         TEvento1 evento1 = new TEvento1();
         evento1.setCampo1(campo1);
         evento1.setCampo2(campo2);
         ....
         return evento1;

     Evento2:
         TEvento2 evento2 = new TEvento2();
         evento2.setCampo1(campo1);
         evento2.setCampo2(campo2);
         ....
         return evento2;
}

Com a nova solução ficaria:


//IEvento é uma interface.
//listaCampos contém todos os campos(atributos) do evento específico.

//Esse código nunca vai mudar!

IEvento evento = Factory.getEvento(tipoEvento);
evento.setCampos(listaCampos);
return evento;

Meio por cima… não sei se consegui me expressar bem…

Mas valeu pelas opiniões… foram bem úteis!! :wink:

Até mais!

O problema nessa historia é vc ter uma classe de tipo.
Veja bem o tipo de um evento é a classe do evento. Vc não precisa ter um enum ou coisa assim.
Além disso a factory pode carregar os dados para vc
O correto ( o mais correto) seria algo assim:

IEvento evento = Factory.newInstance(EventoA.class, dadosDosCampos);  
return evento; 

A assinatura do newInstance seria assim

public <E extends IEvento> E newInstance(Class<E> type , List<Object> dadosDosCampos){
  //cria o objeto
 // preenche os campos
}

Não gostei dessa solução de passar os campos ,mas em termos de design é melhor do que tinha antes.
Essa lista de parametros significa que vc deveria estar escrevendo na realidade


EventoA evento = new EventoA(param1, param2);
return evento;

P.S. Essa nomenclatura da “empresa” é uma porcaria. Faça o que conseguir para mudar isso. Leia “Clean Code” do Robert C Martin e mostre a eles se for necessário.

Entendi!

Na verdade, eu recebo um pacote de bytes, e, a partir deles, preciso criar os objetos eventos. Um dos campos do pacote é o tipo
do evento. Com ele minha classe de Protocolo pode tomar a decisão de que objeto vai retornar. Por isso usei uma enum. Em C++ é muito
mais fácil, por que eu consigo atribuir um inteiro numa enum… enfim…

Agora deixar para a Factory atribuir os dados ou não, acho indiferente.

Valeu pelas dicas… :wink:
Java apavora. (menos enum…rs)

[quote=Jean_Utf]Entendi!

Na verdade, eu recebo um pacote de bytes, e, a partir deles, preciso criar os objetos eventos. Um dos campos do pacote é o tipo
do evento. Com ele minha classe de Protocolo pode tomar a decisão de que objeto vai retornar. Por isso usei uma enum. Em C++ é muito
mais fácil, por que eu consigo atribuir um inteiro numa enum… enfim…

Agora deixar para a Factory atribuir os dados ou não, acho indiferente.
[/quote]

Vc pode achar , mas não é.

enum sim pode receber inteiros. Basta criar um campo que seja um inteiro.

Em C++ eu tenho uma

enum Tipo{A = 1,
          B =2 }

Caso eu fizer

Tipo tipo = 1;

“tipo” vai valer A.

Em java não consigo fazer isso.