Implementação de Reflexão em Java

Conceito de Reflexão

O mecanismo de reflexão permite a inspeção e manipulação dinâmica de classes, métodos e atributos em tempo de execução no Java. Isso possibilita descobrir a estrutura de qualquer classe ou invocar métodos de objetos de forma genérica.

Funcionalidades da Reflexão

  • Identificar a classe de um objeto em tempo de execução
  • Criar instâncias de classes dinamicamente
  • Consultar métodos e atributos de uma classe
  • Invocar métodos de objetos via código genérico
  • Gerar proxies dinâmicos

Classes e Interfaces de Exemplo


interface Legivel {
    void leitura();
}

class Produto implements Legivel {
    private String codigo;
    private String descricao;
    public double preco;

    public Produto() {}

    public Produto(String codigo) {
        this.codigo = codigo;
    }

    public Produto(String codigo, String descricao) {
        this.codigo = codigo;
        this.descricao = descricao;
    }

    public String getCodigo() { return codigo; }
    public void setCodigo(String codigo) { this.codigo = codigo; }
    public String getDescricao() { return descricao; }
    public void setDescricao(String descricao) { this.descricao = descricao; }
    public double getPreco() { return preco; }
    public void setPreco(double preco) { this.preco = preco; }

    public static void atualizar() {}

    @Override
    public void leitura() {}
}

Obtendo uma Classe

Existem três formas principais de obter o objeto Class:


// Método 1: Class.forName
Class> classeA = Class.forName("Produto");

// Método 2: Atributo .class
Class> classeB = Produto.class;

// Método 3: getClass()
Produto item = new Produto();
Class> classeC = item.getClass();

Recuperando Atributos

Use getDeclaredFields() para obter todos os atributos declarados na classe, incluindo privados. getFields() retorna apenas os públicos.


Class> classe = Class.forName("Produto");
Field[] campos = classe.getDeclaredFields();
for (Field campo : campos) {
    System.out.println(campo);
}

Recuperando Métodos

getMethods() lista todos os métodos públicos, incluindo herdados de Object.


Class> classe = Class.forName("Produto");
Method[] metodos = classe.getMethods();
for (Method metodo : metodos) {
    System.out.println(metodo);
}

Recuperando Interfaces e Superclase


Class> classe = Class.forName("Produto");
Class>[] interfaces = classe.getInterfaces();
Class> superclasse = classe.getSuperclass();

Recuperando Construtores


Class> classe = Class.forName("Produto");
Constructor>[] construtores = classe.getConstructors();
for (Constructor> construtor : construtores) {
    System.out.println(construtor);
}

Exemplo Prático 1: Criando uma Instância e Chamando Métodos


Class> classe = Class.forName("Produto");
Object obj = classe.newInstance();
Produto prod = (Produto) obj;
prod.setCodigo("X100");
prod.setDescricao("Widget");
System.out.println("Código: " + prod.getCodigo() + ", Descrição: " + prod.getDescricao());

Exemplo Prático 2: Modificando Atributos Privados


Class> classe = Class.forName("Produto");
Object obj = classe.newInstance();
Field codigoField = classe.getDeclaredField("codigo");
codigoField.setAccessible(true); // Permite acesso a campos privados
codigoField.set(obj, "Y200");
System.out.println(codigoField.get(obj));

Exemplo Prático 3: Operações Combinadas


Class> classe = Class.forName("Produto");
Object obj = classe.newInstance();
Field codigoField = classe.getDeclaredField("codigo");
codigoField.setAccessible(true);
codigoField.set(obj, "Z300");

Method setDescricao = classe.getDeclaredMethod("setDescricao", String.class);
setDescricao.setAccessible(true);
setDescricao.invoke(obj, "Componente");

Field descField = classe.getDeclaredField("descricao");
descField.setAccessible(true);
String descricao = (String) descField.get(obj);
System.out.println("Descrição: " + descricao);

Method getDescricao = classe.getDeclaredMethod("getDescricao");
getDescricao.setAccessible(true);
String descRetorno = (String) getDescricao.invoke(obj);
System.out.println("Método getDescricao: " + descRetorno);

Exemplo Prático 4: Métodos e Atributos Estáticos

Considere a classe Utilitario:


class Utilitario {
    public static String nome = "padrao";
    public static void mostrarMensagem() { System.out.println("Mensagem estática"); }
    public static String obterDica() { return "Dica"; }
    public static void processar(String texto) { System.out.println("Processando: " + texto); }
    public static String calcular(int valor) { return "Resultado: " + valor; }
}

Exemplo de uso:


Class> classe = Class.forName("Utilitario");
Field nomeField = classe.getDeclaredField("nome");
String valorNome = (String) nomeField.get(null); // Acesso a atributo estático
System.out.println(valorNome);

Method mostrar = classe.getDeclaredMethod("mostrarMensagem");
mostrar.invoke(null);

Method obter = classe.getDeclaredMethod("obterDica");
String dica = (String) obter.invoke(null);
System.out.println("Dica: " + dica);

Method processar = classe.getDeclaredMethod("processar", String.class);
processar.invoke(null, "teste");

Method calcular = classe.getDeclaredMethod("calcular", int.class);
String resultado = (String) calcular.invoke(null, 5);
System.out.println(resultado);

Criando Instâncias com Construtores Específicos


Class> classe = Class.forName("Produto");

// Construtor sem parâmetros
Object obj1 = classe.newInstance();

// Construtor com um parâmetro
Constructor> constr1 = classe.getDeclaredConstructor(String.class);
Object obj2 = constr1.newInstance("A123");

// Construtor com dois parâmetros
Constructor> constr2 = classe.getDeclaredConstructor(String.class, String.class);
Object obj3 = constr2.newInstance("B456", "Peça");

Resumo das APIs de Reflexão

Para construtores:

  • getConstructor(Class<?>...) – Retorna um construtor público específico.
  • getConstructors() – Retorna todos os construtores públicos.
  • getDeclaredConstructor(Class<?>...) – Retorna um construtor específico, independentemente do modificador.
  • getDeclaredConstructors() – Retorna todos os construtores da classe.

Para métodos:

  • getMethod(String, Class<?>...) – Retorna um método público específico.
  • getMethods() – Retorna todos os métodos públicos.
  • getDeclaredMethod(String, Class<?>...) – Retorna um método específico.
  • getDeclaredMethods() – Retorna todos os métodos declarados.

Para atributos:

  • getField(String) – Retorna um atributo público específico.
  • getFields() – Retorna todos os atributos públicos.
  • getDeclaredField(String) – Retorna um atributo específico.
  • getDeclaredFields() – Retorna todos os atributos declarados.

Tags: java Reflexão POO APIs de Reflexão

Publicado em 6-14 06:40 por Thomas