Tempo de leitura: menos de 1 minuto
Há alguns dias, falei aqui no blog sobre Annotation e Reflection, falei um pouco de conceitos e o que o Java oferece de recursos para trabalhar com elas. Hoje vamos falar um pouco mais sobre reflexão.
No projeto que trabalho, não usamos diretamente a API javax.reflection, por ser muito poderosa, ela acaba sendo bem complexa de entender e usar. Por isso preferimos abstrair o uso de reflexão da API mais flexível e amigável. Aqui usamos a o Mirror.
Mirror disponibiliza uma camada DSL simples sobre a javax.refelection, com o objetivo de tornar essa poderosa API mais amigável. Usar Mirror anula os tratamento chatos de exceções e muitas linhas de códigos ilegíveis. No site oficial do projeto, tem um exemplo bem legal evidenciando como é simples trabalhar com o Mirror, que transcrevo aqui:
Dê uma olhada no seguinte código:
[code language=”java”]
// Vamos apenas definir o valor de um atributo. Deveria ser uma tarefa fácil, certo?
// "obj" é o objeto contendo o atributo que queremos definir o valor.
Field toSet = null;
for (Field f : obj.getClass().getDeclaredFields()) {
// Busque todos os fields DECLARADOS na classe que define o objeto target
if (f.getName().equals("field")) {
toSet = f;
}
}
if (toSet != null &&(toSet.getModifiers() & Modifier.STATIC) == 0) {
toSet.setAccessible(true);
toSet.set(target, value);
}
[/code]Ah! Que código mais sujo! Completamente ilegível. O quê Modifier.STATIC está fazendo no meu código?
…
Agora usando Mirror:[code language=”java”]
new Mirror().on(target).set().field(fieldName)
.withValue(value);
[/code]
E aí? O que acharam? Não se preocupe se o método existe ou está acessível… Simplesmente use!
Exemplos de uso
Deixo abaixo alguns exemplo de uso.
Refletindo Atributos e Métodos
Refletir um atributo através do nome:
[code language=”java”]
//devolverá null se não encontrar
Field f = new Mirror().on(MinhaClasse.class).reflect()
.field("nomeAtributo");
[/code]
Refletir todos os campos de uma classe:
[code language=”java”]
//devolverá uma lista vazia se não encontrar o atributo
List<Field> l = new Mirror().on(MinhaClasse.class).reflectAll()
.fields();
[/code]
Refletindo um método pelo nome:
[code language=”java”]
//retornará null se não for encontrado
Method m = new Mirror().on(MinhaClasse.class).reflect()
.method("nomeMetodo").withoutArgs();
[/code]
Refletindo um método pelos seus argumentos:
[code language=”java”]
//retornará null se não for encontrado
Method m = new Mirror().on(MinhaClasse.class).reflect()
.method("nomeMetodo").withArgs(String.class, Object.class);
[/code]
Atribuindo valores
Atribuindo valores em um atributo estático:
[code language=”java”]
new Mirror().on(MinhaClasse.class).set()
.field("nomeAtributo").withValue(valor);
[/code]
Atribuindo valor em um atributo de instância:
[code language=”java”]
new Mirror().on(instanciaDoObjeto).set()
.field("nomeAtributo").withValue(valor);
[/code]
Invocando Métodos e Construtores
Invocando um método estático:
[code language=”java”]
Object retorno = new Mirror().on(MinhaClasse.class).invoke()
.method("nomeMetodo").withArgs(valor1, valor2);
[/code]
Invocando um método de instância:
[code language=”java”]
Object returnValue = new Mirror().on(instanciaDoObjeto).invoke()
.method("nomeMetodo").withoutArgs();
[/code]
Invocando um getter ou setter:
[code language=”java”]
//getter
Object returnValue = new Mirror().on(instanciaDoObjeto)
.invoke().getterFor("nomeAtributo");
//setter
new Mirror().on(instanciaDoObjeto).set()
.invoke().setterFor("nomeAtributo").withValue(valor);
[/code]
Invocando um construtor:
[code language=”java”]
T t = new Mirror().on(MinhaClasse.class).invoke()
.constructor().withoutArgs();
[/code]
Refletindo anotações
Você pode facilmente refletir todas as anotações de uma classe:
[code language=”java”]
List<Annotation> annotations = new Mirror().on(MinhaClasse.class)
.reflectAll().annotations().atClass();
[/code]
Você pode facilmente refletir todas as anotações de uma classe:
[code language=”java”]
List<Annotation> annotations = new Mirror().on(MinhaClasse.class)
.reflectAll().annotations().atClass();
[/code]
Da mesma forma que você também pode facilmente refletir todas as anotações de um atributo ou de um método:
[code language=”java”]
//atributos
List<Annotation> fieldAnnotations = new Mirror().on(MinhaClasse.class)
.reflectAll().annotations().atField("nomeAtributo");
//métodos
List<Annotation> methodAnnotations = new Mirror().on(MinhaClasse.class)
.reflectAll().annotations().atMethod("nomeMetodo")
.withoutArgs();
[/code]
Todos os exemplos deste post e muito mais estão disponíveis no site oficial.
Valeu pessoal.
Link permanente
Em comparação a API javax.refelection, o Mirror é bem mais tranquilo mesmo! rsrs