Dominando Java Reflection API: Guia Prático com Exemplos de Código
O que é Reflection em Java?
Java Reflection é processo de analisar e modificar todas capacidades de uma classe em tempo de execução. Reflection API em Java é usada para manipular classe e seus membros que incluem campos, métodos, construtores, etc. em tempo de execução.
Uma vantagem da reflection API em Java é que pode manipular membros privados da classe também.
Pacote java.lang.reflect provê muitas classes para implementar reflection java. Métodos da classe java.lang.Class são usados para reunir metadados completos de uma classe particular.
Neste tutorial, você aprenderá:
- O que é Reflection
- Classes no pacote java.lang.reflect
- Métodos usados em java.lang.Class
- Como obter informação completa sobre uma classe
- Exemplo 1: Como obter Metadados de Classe
- Exemplo 2: Como obter Metadados de Variável
- Exemplo 3: Como obter Metadados de Método
- Exemplo 4: Como obter Metadados de Construtores
Classes no pacote java.lang.reflect
Lista de classes Java em java.lang.package para implementar reflection:
- Field: Usada para reunir informação declarativa como tipo de dado, modificador de acesso, nome e valor de variável.
- Method: Usada para reunir informação declarativa como modificador de acesso, tipo de retorno, nome, tipos de parâmetro e tipo de exceção de método.
- Constructor: Usada para reunir informação declarativa como modificador de acesso, nome e tipos de parâmetro de construtor.
- Modifier: Usada para reunir informação sobre modificador de acesso particular.
Métodos usados em java.lang.Class
- Public String getName(): Retorna nome da classe.
- public Class getSuperclass(): Retorna referência da superclasse.
- Public Class[] getInterfaces(): Retorna array de interfaces implementadas pela classe especificada.
- Public int getModifiers(): Retorna valor inteiro representando modificadores da classe especificada que precisa ser passado como parâmetro para public static String toString(int i) que retorna especificador de acesso para classe dada.
Como obter informação completa sobre uma classe
Para obter informação sobre variáveis, métodos e construtores de uma classe, precisamos criar objeto da classe.
public class Guru99ClassObjectCreation {
public static void main (String[] args) throws ClassNotFoundException {
//1 - Usando método Class.forName()
Class c1 = Class.forName("Guru99ClassObjectCreation");
//2- Usando método getClass()
Guru99ClassObjectCreation guru99Obj = new Guru99ClassObjectCreation();
Class c2 = guru99Obj.getClass();
//3- Usando .class
Class c3 = Guru99ClassObjectCreation.class;
}
}
Exemplo 1: Como obter Metadados de Classe
Exemplo a seguir mostra como obter metadados como: Nome da classe, nome da superclasse, interfaces implementadas, e modificadores de acesso de uma classe.
Obteremos metadados da classe abaixo nomeada Guru99Base.class:

import java.io.Serializable;
public abstract class Guru99Base implements Serializable,Cloneable {
}
- Nome da classe é: Guru99Base
- Seus modificadores de acesso são: public e abstract
- Implementou interfaces: Serializable e Cloneable
- Como não estendeu nenhuma classe explicitamente, sua superclasse é: java.lang.Object
Classe abaixo obterá meta dados de Guru99Base.class e imprimirá:

import java.lang.reflect.Modifier;
public class Guru99GetclassMetaData {
public static void main (String [] args) throws ClassNotFoundException {
// Criar objeto Class para Guru99Base.class
Class<Guru99Base> guru99ClassObj = Guru99Base.class;
// Imprimir nome da classe
System.out.println("Nome da classe é: " + guru99ClassObj.getName());
// Imprimir nome da superclasse
System.out.println("Nome da superclasse é: " + guru99ClassObj.getSuperclass().getName());
// Obter lista de interfaces implementadas como array de Class usando getInterfaces()
Class[] guru99InterfaceList = guru99ClassObj.getInterfaces();
// Imprimir interfaces implementadas usando foreach loop
System.out.print("Interfaces implementadas são: ");
for (Class guru99class1 : guru99InterfaceList) {
System.out.print(guru99class1.getName() + " ");
}
System.out.println();
// Obter modificadores de acesso usando getModifiers() e toString() de java.lang.reflect.Modifier
int guru99AccessModifier = guru99ClassObj.getModifiers();
// Imprimir modificadores de acesso
System.out.println("Modificadores de acesso da classe são: " + Modifier.toString(guru99AccessModifier));
}
}
- Imprimir nome da classe usando método getName
- Imprimir nome da superclasse usando getSuperClass().getName()
- Imprimir nome das interfaces implementadas
- Imprimir modificadores de acesso usados pela classe


Exemplo 2: Como obter Metadados de Variável
Exemplos a seguir mostram como obter metadados de variável:
Aqui, criamos classe nomeada Guru99VariableMetaData.class com algumas variáveis:
package guru;
public class Guru99VariableMetaData {
public static int guru99IntVar1=1111;
static int guru99IntVar2=2222;
static String guru99StringVar1="guru99.com";
static String guru99StringVar2="Learning Reflection API";
}
Passos para obter metadados sobre variáveis na classe acima:
- Criar objeto da classe acima i.e. Guru99VariableMetaData.class como abaixo:
Guru99VariableMetaData guru99ClassVar = new Guru99VariableMetaData(); Class guru99ClassObjVar = guru99ClassVar.getClass();
- Obter metadados na forma de array Field usando getFields() ou getDeclaredFields():
Field[] guru99Field1 = guru99ClassObjVar.getFields(); Field[] guru99Field2 = guru99ClassObjVar.getDeclaredFields();
getFields() retorna metadados de variáveis public da classe especificada bem como de sua superclasse.
getDeclaredFields() retorna metadados de todas variáveis da classe especificada apenas.
- Obter nome das variáveis usando "public String getName()" method.
- Obter tipo de dado das variáveis usando "public Class getType()" method.
- Obter valor da variável usando "public xxx get(Field)" method. Aqui, xxx pode ser byte, short ou qualquer tipo de valor que queira buscar.
- Obter modificadores de acesso das variáveis usando getModifier() e Modifier.toString(int i) methods.
Aqui, escrevemos classe para obter metadados das variáveis presentes na classe Guru99VariableMetaData.class:

package guru; import java.lang.reflect.Field; public class Guru99VariableMetaDataTest { public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException { // Criar objeto Class para Guru99VariableMetaData.class Guru99VariableMetaData guru99ClassVar = new Guru99VariableMetaData(); Class guru99ClassObjVar = guru99ClassVar.getClass(); // Obter metadados de todos os campos da classe Guru99VariableMetaData Field[] guru99Field1 = guru99ClassObjVar.getDeclaredFields(); // Imprimir nome, tipos de dado, modificadores de acesso e valores das variáveis da classe especificada for(Field field : guru99Field1) { System.out.println("Nome da variável: " + field.getName()); System.out.println("Tipo de dado da variável: " + field.getType()); int guru99AccessModifiers = field.getModifiers(); System.out.println("Modificadores de acesso da variável: " + Modifier.toString(guru99AccessModifiers)); System.out.println("Valor da variável: " + field.get(guru99ClassVar)); System.out.println(); System.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *"); } } } - Criado objeto classe para Guru99VariableMetaData.class
- Obtido todos metadados das variáveis em array Field
- Imprimidos todos nomes das variáveis na classe Guru99VariableMetaData.class
- Imprimidos todos tipos de dado das variáveis na classe Guru99VariableMetaData.class
- Imprimidos todos modificadores de acesso das variáveis na classe Guru99VariableMetaData.class
- Imprimidos valores de todas variáveis na classe Guru99VariableMetaData.class
- Criar objeto classe da classe acima i.e. Guru99MethodMetaData.class:
Guru99MethodMetaData guru99ClassVar = new Guru99MethodMetaData(); Class guru99ClassObjVar = guru99ClassVar.getClass();
- Obter informação de métodos em array Method usando getMethods() e getDeclaredMethods():
Method[] guru99Method1 = guru99ClassObjVar.getMethods(); Method[] guru99Method2 = guru99ClassObjVar.getDeclaredMethods();
getMethods() retorna metadados de métodos public da classe especificada bem como de sua superclasse.
getDeclaredMethods() retorna metadados de todos métodos da classe especificada apenas.
- Obter nome do método usando getName().
- Obter tipo de retorno do método usando getReturnType().
- Obter modificadores de acesso dos métodos usando getModifiers() e Modifier.toString(int i).
- Obter tipos de parâmetros do método usando getParameterTypes() que retorna array de Class.
- Obter exceções lançadas usando getExceptionTypes() que retorna array de Class.
- Criado objeto classe para Guru99MethodMetaData.class
- Obtido todos metadados de todos métodos em array Method
- Imprimidos todos nomes de métodos presentes na classe Guru99MethodMetaData.class
- Imprimidos tipos de retorno dos métodos na classe Guru99MethodMetaData.class
- Imprimidos todos modificadores de acesso dos métodos na classe Guru99MethodMetaData.class
- Imprimidos tipos de parâmetros dos métodos em Guru99MethodMetaData.class
- Imprimidas exceções lançadas por métodos em Guru99MethodMetaData.class
- Criado objeto classe para Guru99Constructor.class
- Obtido todos metadados de todos construtores em array Constructor
- Imprimidos todos nomes dos construtores presentes na classe Guru99Constructor.class
- Imprimidos todos modificadores de acesso dos construtores na classe Guru99Constructor.class
- Imprimidos tipos de parâmetros dos construtores em Guru99Constructor.class
- Imprimidas exceções lançadas por construtores em Guru99Constructor.class
- Programação reflection em Java ajuda recuperar e modificar informação sobre Classes e membros como variáveis, métodos, construtores.
- Reflection API em Java pode ser implementada usando classes em java.lang.reflect e métodos de java.lang.Class.
- Métodos comuns de java.lang.Class: getName(), getSuperclass(), getInterfaces(), getModifiers() etc.
- Classes comuns em java.lang.reflect: Field, Method, Constructor, Modifier, etc.
- Reflection API pode acessar métodos e variáveis privadas de classe o que pode ser ameaça de segurança.
- Reflection API é capacidade poderosa do Java, mas vem com overheads como performance mais lenta, vulnerabilidade de segurança, e questões de permissão. Portanto, reflection API deve ser tratado como último recurso para realizar operação.


Exemplo 3: Como obter Metadados de Método
Exemplos a seguir mostram como obter metadados de método:
Aqui, criamos classe nomeada Guru99MethodMetaData.class com alguns métodos:

package guru;
import java.sql.SQLException;
public class Guru99MethodMetaData {
public void guru99Add(int primeiroElemento, int segundoElemento, String resultado) throws ClassNotFoundException, ClassCastException {
System.out.println("Método demo para Reflection API");
}
public String guru99Search(String searchString) throws ArithmeticException, InterruptedException {
System.out.println("Método demo para Reflection API");
return null;
}
public void guru99Delete(String deleteString) throws SQLException {
System.out.println("Método demo para Reflection API");
}
}
Passos para obter metadados sobre métodos na classe acima:
Aqui, escrevemos classe para obter metadados dos métodos presentes na classe Guru99MethodMetaData.class:

package guru;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class Guru99MethodMetaDataTest {
public static void main(String[] args) {
// Criar objeto Class para Guru99MethodMetaData.class
Class guru99ClassObj = Guru99MethodMetaData.class;
// Obter metadados ou informação de todos métodos da classe usando getDeclaredMethods()
Method[] guru99Methods = guru99ClassObj.getDeclaredMethods();
for(Method method : guru99Methods) {
// Imprimir nomes dos métodos
System.out.println("Nome do método: " + method.getName());
// Imprimir tipo de retorno dos métodos
System.out.println("Tipo de retorno do método: " + method.getReturnType());
// Obter lista de modificadores de acesso e imprimir
int guru99ModifierList = method.getModifiers();
System.out.println("Modificadores de acesso do método: " + Modifier.toString(guru99ModifierList));
// Obter e imprimir parâmetros dos métodos
Class[] guru99ParamList = method.getParameterTypes();
System.out.print("Tipos de parâmetros do método: ");
for (Class class1 : guru99ParamList) {
System.out.println(class1.getName() + " ");
}
System.out.println();
// Obter e imprimir exceções lançadas pelo método
Class[] guru99ExceptionList = method.getExceptionTypes();
System.out.print("Exceções lançadas pelo método: ");
for (Class class1 : guru99ExceptionList) {
System.out.println(class1.getName() + " ");
}
System.out.println();
System.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *");
}
}
}


Exemplo 4: Como obter Metadados de Construtores
Exemplos a seguir mostram como obter metadados de construtores:
Aqui, criamos classe nomeada Guru99Constructor.class com diferentes construtores:

package guru;
import java.rmi.RemoteException;
import java.sql.SQLException;
public class Guru99Constructor {
public Guru99Constructor(int no) throws ClassCastException, ArithmeticException { }
public Guru99Constructor(int no, String nome) throws RemoteException, SQLException { }
public Guru99Constructor(int no, String nome, String endereco) throws InterruptedException { }
}
Aqui, escrevemos classe para obter metadados dos construtores presentes na classe Guru99Constructor.class:

package guru;
import java.lang.reflect.Constructor;
public class Guru99ConstructorMetaDataTest {
public static void main(String[] args) {
// Criar objeto Class para Guru99Constructor.class
Class guru99Class = Guru99Constructor.class;
// Obter toda informação de construtores em array Constructor
Constructor[] guru99ConstructorList = guru99Class.getConstructors();
for (Constructor constructor : guru99ConstructorList) {
// Imprimir nome de cada construtor
System.out.println("Nome do construtor: " + constructor.getName());
// Obter e imprimir modificadores de acesso de cada construtor
int guru99Modifiers = constructor.getModifiers();
System.out.println("Modificador do construtor: " + Modifier.toString(guru99Modifiers));
// Obter e imprimir tipos de parâmetros
Class[] guru99ParamList = constructor.getParameterTypes();
System.out.print("Tipos de parâmetros do construtor: ");
for (Class class1 : guru99ParamList) {
System.out.println(class1.getName() + " ");
}
System.out.println();
// Obter e imprimir exceções lançadas por construtores
Class[] guru99ExceptionList = constructor.getExceptionTypes();
System.out.println("Exceções lançadas pelos construtores: ");
for (Class class1 : guru99ExceptionList) {
System.out.println(class1.getName() + " ");
}
System.out.println();
System.out.println("*******************************************");
}
}
}


Resumo:
Java
- Dominando Classes Internas Anônimas em Java: Definição, Sintaxe e Exemplos Práticos
- Dominando Reflection em Java: Inspecionando Classes, Métodos e Campos em Tempo de Execução
- Dominando ObjectInputStream do Java: Guia Completo
- Dominando Java ObjectOutputStream: Serialização, Métodos e Exemplos Práticos
- Classes e Objetos em C++: Guia Prático com Exemplos de Código
- Classes Abstratas em C#: Tutorial Prático com Exemplos de Código
- Entendendo Java String.charAt(): Sintaxe, Tipo de Retorno, Exceções e Exemplo Prático
- Dominando Java String.endsWith(): Como Verificar Sufixos de String com Exemplos
- Lendo Arquivos em Java com BufferedReader – Guia Prático com Exemplos
- Algoritmo Insertion Sort em Java: Exemplo Claro e Guia Passo a Passo