Reflection X Anotações

19 respostas
71C4700

Estamos trabalhando em um projeto, onde queriamos montar um objeto em tempo de execução.
o problema é que alem disso teriamos que mapear o atributo ao metodo get dele.
Assim

// Atributo
private int campo;

//  Metodo que retorna o valor do atributo campo
 public int getCampo(){
 return this.campo;
}

Deveria ter este mapeamento por conta do uso do Reflection, na chamada do metodo.
Então, sugestões ??

19 Respostas

pcalcado

Se você tem getCoisa ligado à coisa porque nao usar JavaBeans ou simplesmente pegar o método na classe cujo nome siga o padrão?

rissato

seguindo os padrões de um objeto POJO vc não precisa de annotations.

TangZero

Mas o problema é que ele monta o objeto em tempo de execução…

71C4700

Venho agrdecer a atenção!
Mas o grande problema é justamente esse, meu objeto é montado em tempo de execução
Eo uso de anotações erá so pra marcar

private String nome;


// Capturar este metodo em tempo de execução
@MeuMetodoDeRetorno(retorno=nome)
public String getNome(){
return this.nome;
}

Seria mais ou menos isso!
Abraços

victorwss

71C4700:
Venho agrdecer a atenção!
Mas o grande problema é justamente esse, meu objeto é montado em tempo de execução
Eo uso de anotações erá so pra marcar

private String nome;


// Capturar este metodo em tempo de execução
@MeuMetodoDeRetorno(retorno=nome)
public String getNome(){
return this.nome;
}

Seria mais ou menos isso!
Abraços

É algo assim?

for (Method metodo : classe.getMethods()) { // Ou getDeclaredMethods()
    MeuMetodoDeRetorno annot = metodo.getAnnotation(MeuMetodoDeRetorno.class);
    if (annot == null) continue;
    Field atributo = classe.getDeclaredField(annot.retorno());
    if (atributo == null) {
        throw new MeuReflectionError(
                "A classe " + classe.getName() +
                " não tem o atributo " + annot.retorno() +
                " para o método " + metodo.getName() + ".");
    }
    // Agora, você faz o que quiser com atributo.
}
pcalcado

Não exatamente. Isso é um debate antigo e apesar de eu concordar com você que metadados específicos descaracterizam POJOs a indústria como um todo assume que POJOs possuem anotações.

Ele é montado ou você o recebe? Pode explicar com um pouquinho mais de contexto, não estou conseguindo entender.

victorwss

Não exatamente. Isso é um debate antigo e apesar de eu concordar com você que metadados específicos descaracterizam POJOs a indústria como um todo assume que POJOs possuem anotações.

Na verdade, já vi uma crítica a isso que tenho que concordar: Plain OLD Java Object (POJO) não tem anotações. Esses são os PNAO (Plain New Annotated Object) ou PNAJO (Plain New Annotated Java Object).

71C4700

Ta ai eu tanto recebo quanto instancio o objeto em tempo de execução!
Ta dificl de sair algo
tentei ajustar pro meu problema a solução do victorwss
Mas ainda nao consegui fazer necessariarmente o que desejo.
não é nada muito dificil mais devemos estar deichando escapar um pequeno detalhe!
Mas agradeço pela preucupação !

pcalcado

Bom, eu até agora sequer consegui o problema que você tem.

71C4700

Tem como resolver este pepino
Usando reflection ??

class Enredeco{
private String rua;
//Getters e Setters 
}

class Pessoa{
private Endereco endereco;
//Getters e Setters 
}

E agora fazer o seguinte

Pessoa pessoa = new Pessoa();
pessoa.getEndereco().getRua();// Nesta linha ta o meu problema

Queria fazer isso, mas lembrando que tanto criando quanto recebendo este objeto Pessoa, deveria funcionar.

pcalcado

O que você quer fazer é chamar um método no retorno de um metodo dinamicamente?

71C4700

Mais ou menos isso !
mas é por ai

pcalcado

E qual o problema de procurar um método chamado get<nome do atributo> no objeto retornado?

ViniGodoy

Não seria problema ter um objeto criado em tempo de execução, mas uma classe criada em tempo de execução.

Como o segundo caso efetivamente não existe em Java (pelo menos ainda), você ainda pode executar reflection no objeto, mesmo que ele seja criado através de reflexão, ou seja a instância de um script groovy.

victorwss

ViniGodoy:
Não seria problema ter um objeto criado em tempo de execução, mas uma classe criada em tempo de execução.

Como o segundo caso efetivamente não existe em Java (pelo menos ainda), você ainda pode executar reflection no objeto, mesmo que ele seja criado através de reflexão, ou seja a instância de um script groovy.

Talvez classes Proxy ou geração on-the-fly de bytescodes resolvam.
Embora isso normalmente seja usar uma bomba atômica para matar uma formiga.

rildolho

Como o assunto tb é Annotations:

Li a MundoJAVA nº 18, e, em seu último artigo, há comparações de JAVA com Ruby e Python quanto à verbosidade. Lembro-me que o autor do artigo comentou que muito da verbosidade (clareza) encontrada em JAVA poderia ser diminuída com o uso de um mecanismo de Annotations com relação à criação de métodos acessadores e contrutores em tempo de compilação. Algo como:

[color=darkblue]@Constructor(params={“nome”})

@Constructor(params={“nome,pacientes”})

public class Medico {

@Property String nome;
@Property(write=false) List<Paciente> pacientes;

public void addPacientes(Paciente paciente) {
    pacientes.add(paciente);
}

}
[/color]
#Versão Ruby:
[color=darkred]class Medico
attr_accessor :nome
attr_reader :pacientes

def initialize(nome, pacientes=[])
    @nome = nome
    @pacientes = pacientes
end

def addPaciente(paciente)
    @pacientes << paciente
end

end
[/color]

Achei a idéia interessante e pesquisei, li, reli, mas não consegui implementar!
Alguém poderia me mostrar como?

pcalcado

Não sei exatamente o que o autor tem em mente mas este exemplo é bem estranho. De qualquer forma, tente ler sobre injeção de dependências, acho que no fundo é isso que ele tentou dizer.

rildolho

Amigo,

A anotação “@Construtor” adicionaria à classe Medico dois construtores:

[color=darkred]public Medico(String nome) {

this.nome = nome;

}
public Medico(String nome, List<Paciente> pacientes) {

this(nome);

this.pacientes = pacientes;

}

[/color]

E a anotação “@Property” adionaria os métodos [color=darkred]get[/color] e [color=darkred]set[/color] para a propriedade nome e [color=darkred]get[/color] para pacientes.

Será que isso é possível com annotations?
Ainda continua estranho pra vc?
Sei q vc fomenta a busca pelo conhecimento, mas o pouco q entendo de DI que parece com IoC e então não se trataria disso, mas acho q vc ou outro programador mais experto aqui no GUJ conseguem resolver essa!

Na minha opinião, seria um mecanismo muito legal para JAVA!

pcalcado

E qual a vantagem disso em Java? Gerar código para construtor ou get/set burro qualquer IDE faz e fazer isso em tempo de eecução não diminui a verbosidade da linguagem.

Na verdade você sequer precisaria gerar construtores. DI (que é uma forma de IoC) poderia simplesmente injetar os atributos diretamente, sem setter ou construtor.

A verbosidade do Java não está relacionada com get/set e sim com a forma com que ela usa tipageme stática, onde você tem que dar papinha pro compilador o tempo todo. Fora o modelo de meta-programação fraco.

Criado 25 de julho de 2008
Ultima resposta 29 de jul. de 2008
Respostas 19
Participantes 7