Reflexão e Anotações
Mateus Parente
REAPROVEITAR
REUTILIZAR
public class Funcionario {
private String nome;
private String endereco;
private Integer idade;
private BigDecimal salario;
...
}
VALIDADOR
VALIDADOR
!= null
TIPOS DE SOLUÇÕES
sofisticada
gambiarra
criativa
public class Validador {
public List<String> validar(Funcionario funcionario){
List<String> invalidos = new ArrayList<>();
if(funcionario.getNome() == null)
invalidos.add("nome");
if(funcionario.getEndereco() == null)
invalidos.add("endereco");
return invalidos;
}
}
PROBLEMAS
PROBLEMAS
nome de atributo
PROBLEMAS
nome de atributo
só funciona para Funcionario
PROBLEMAS
nome de atributo
só funciona para Funcionario
inclusão de atributo
PROBLEMAS
nome de atributo
só funciona para Funcionario
inclusão de atributo
código extenso
public class Validador {
public List<String> validar(Funcionario funcionario){
List<String> invalidos = new ArrayList<>();
if(funcionario.getNome() == null)
invalidos.add("nome");
if(funcionario.getEndereco() == null)
invalidos.add("endereco");
if(funcionario.getTelefone() == null)
invalidos.add("telefone");
if(funcionario.getDataDeNascimento() == null)
invalidos.add("dataDeNascimento");
if(funcionario.getIdade() == null)
invalidos.add("idade");
return invalidos;
}
}
HORA DE
REFATORAR
MISSÃO
desconhecer meus
atributos
public class Validador {
public List<String> validar(Funcionario funcionario){
List<String> invalidos = new ArrayList<>();
Atributo[] atributos = funcionario.getAtributos();
for(Atributo atributo : atributos){
if(atributo.getValue() == null)
invalidos.add(atributo.getNome());
}
return invalidos;
}
}
Probleminha
Atributos não estão no
Objeto, e sim, na Classe.
public class Validador {
public List<String> validar(Funcionario funcionario){
List<String> invalidos = new ArrayList<>();
Classe classeDoFuncionario = funcionario.getClasse();
Atributo[] atributos = classeDoFuncionario.getAtributos();
for(Atributo atributo : atributos){
if(atributo.getValue() == null)
invalidos.add(atributo.getNome());
}
return invalidos;
}
}
Outro
Probleminha
Valor dos Atributos não estão na
classe, e sim, no Objeto
public class Validador {
public List<String> validar(Funcionario funcionario){
List<String> invalidos = new ArrayList<>();
Classe classeDoFuncionario = funcionario.getClasse();
Atributo[] atributos = classeDoFuncionario.getAtributos();
for(Atributo atributo : atributos){
Object valor = atributo.buscar(funcionario);
if(valor == null)
invalidos.add(atributo.getNome());
}
return invalidos;
}
}
VAMOS A
REALIDADE
Classjava.lang.Class
Class
funcionario.getClass();
Funcionario.class;
Class.forName(“br.com.javou.Funcionario”)
FIELDjava.lang.reflect.Field
Field
clazz.getFields();
clazz.getDeclaredFields();
Adaptando...
public class Validador {
public List<String> validar(Funcionario funcionario){
List<String> invalidos = new ArrayList<>();
Class<?> classeDoFuncionario = funcionario.getClass();
Field[] atributos = classeDoFuncionario.getFields();
for(Field atributo : atributos){
Object valor = atributo.get(funcionario);
if(valor == null)
invalidos.add(atributo.getName());
}
return invalidos;
}
}
Pra variar...
Probleminha
classeDoFuncionario.getFields()
ESTÁ VAZIA
getFields()
x
getDeclaredFields()
Class
getFields()
x
getDeclaredFields()
Class
publicos + superclass
publicos + privados
public class Validador {
public List<String> validar(Funcionario funcionario){
List<String> invalidos = new ArrayList<>();
Class<?> classeDoFuncionario = funcionario.getClass();
Field[] atributos = classeDoFuncionario.getDeclaredFields();
for(Field atributo : atributos){
Object valor = atributo.get(funcionario);
if(valor == null)
invalidos.add(atributo.getName());
}
return invalidos;
}
}
java.lang.IllegalAccessException: Class
br.com.reflections.validadores.Validador can not access a member of class
br.com.reflections.models.Funcionario with modifiers "private".
…
public List<String> validar(Funcionario funcionario){
List<String> invalidos = new ArrayList<>();
Class<?> classeDoFuncionario = funcionario.getClass();
Field[] atributos = classeDoFuncionario.getDeclaredFields();
for(Field atributo : atributos){
atributo.setAccessible(true);
Object valor = atributo.get(funcionario);
if(valor == null)
invalidos.add(atributo.getName());
}
return invalidos;
}
public class Funcionario {
private String nome;
private String endereco;
private Integer idade;
private BigDecimal salario;
...
}
public void test(){
Funcionario funcionario = new Funcionario();
funcionario.setNome(“Mateus”);
funcionario.setEndereco(“Lagoa Redonda”);
Validador validador = new Validador();
List<String> erros = validador.valida(funcionario);
assertTrue(erros.contains(“idade”));
assertTrue(erros.contains(“salario”));
assertFalse(erros.contains(“nome”));
assertFalse(erros.contains(“endereco”));
}
@Test
Tudo funcionando
HORA DE
REFATORAR
…
public List<String> validar(Object entidade){
List<String> invalidos = new ArrayList<>();
Class<?> clazz = entidade.getClass();
Field[] atributos = clazz.getDeclaredFields();
for(Field atributo : atributos){
atributo.setAccessible(true);
Object valor = atributo.get(entidade);
if(valor == null)
invalidos.add(atributo.getName());
}
return invalidos;
}
COMPONENTES
REUTILIZÁVEIS
PERSONALIZAR
MENSAGENS
public class Funcionario {
private String Nome;
private String Endereço;
private Integer Idade;
private BigDecimal Salário;
...
}
ANOTAÇÕES
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Validacao {
String descricao();
}
public class Funcionario {
@Validacao(descricao = ‘Nome completo’)
private String nome;
@Validacao(descricao = ‘Endereço’)
private String endereco;
…
}
…
Class<?> clazz = entidade.getClass();
Field[] atributos = clazz.getDeclaredFields();
for(Field atributo : atributos){
atributo.setAccessible(true);
Object valor = atributo.get(entidade);
if(valor == null) {
if(atributo.isAnnotationPresent(Validacao.class)){
Validacao validacao =
atributo.getAnnotation(Validacao.class);
invalidos.add(validacao.descricao());
}
}
}
desvantagens
complexidade /
performance
obrigado
Perguntas
Referencias:
Componentes Reutilizáveis em Java com Reflexão e Anotações - Eduardo Guerra
Laboratório Java com Testes, XML e Design Patterns - Caelum

Reflexão e Anotações no mundo Java