Java Tutorial da API Reflection com exemplo

โšก Resumo Inteligente

Java A API de Reflexรฃo analisa e modifica as capacidades de uma classe em tempo de execuรงรฃo, incluindo seus campos, mรฉtodos e construtores. Este recurso explica o pacote java.lang.reflect, os principais mรฉtodos de java.lang.Class e quatro exemplos que leem os metadados de uma classe, variรกvel, mรฉtodo e construtor.

  • ๐Ÿ” Definiรงรฃo: A reflexรฃo inspeciona e modifica classes e seus membros em tempo de execuรงรฃo, inclusive os privados.
  • ๐Ÿ“ฆ Pacote Reflect: As classes Field, Method, Constructor e Modifier reรบnem informaรงรตes declarativas sobre os membros.
  • ๐Ÿท๏ธ Mรฉtodos de classe: getName(), getSuperclass(), getInterfaces() e getModifiers() retornam metadados da classe principal.
  • ๐Ÿงช Exemplos prรกticos: Quatro programas extract metadados de uma classe, variรกveis, mรฉtodos e construtores.
  • โš ๏ธ Cuidado: O Reflection pode acessar membros privados e รฉ mais lento, portanto, use-o como รบltimo recurso.

Java Tutorial da API de Reflexรฃo

O que รฉ reflexรฃo Java?

Java A reflexรฃo รฉ o processo de analisar e modificar todas as capacidades de uma classe em tempo de execuรงรฃo. A API de Reflexรฃo em Java ร‰ utilizado para manipular uma classe e seus membros, incluindo campos, mรฉtodos, construtores, etc., em tempo de execuรงรฃo.

Uma das vantagens da API de Reflexรฃo รฉ Java ร‰ que tambรฉm pode manipular os membros privados da classe.

O pacote java.lang.reflect fornece vรกrias classes para implementar reflexรฃo. Os mรฉtodos da classe java.lang.Class sรฃo usados โ€‹โ€‹para coletar os metadados completos de uma classe especรญfica.

Classe no pacote java.lang.reflect

Segue uma lista de vรกrio Java aulas No pacote java.lang.reflect para implementar reflexรฃo:

  • Campo: Essa classe รฉ usada para reunir informaรงรตes declarativas, como o tipo de dados, o modificador de acesso, o nome e o valor de uma variรกvel.
  • Mรฉtodo: Essa classe รฉ usada para reunir informaรงรตes declarativas, como o modificador de acesso, o tipo de retorno, o nome, os tipos de parรขmetros e o tipo de exceรงรฃo de um mรฉtodo.
  • Construtor: Esta classe รฉ usada para reunir informaรงรตes declarativas, como o modificador de acesso, o nome e os tipos de parรขmetros de um construtor.
  • Editar: Esta classe รฉ usada para coletar informaรงรตes sobre um modificador de acesso especรญfico.

Mรฉtodos usados โ€‹โ€‹em java.lang.Class

  • public String getName(): Retorna o nome da classe.
  • public Class getSuperclass(): Retorna a referรชncia da superclasse.
  • public Class[] getInterfaces(): Retorna uma matriz de interfaces implementadas pela classe especificada.
  • public int getModifiers(): Retorna um valor inteiro representando os modificadores da classe especificada, que precisa ser passado como parรขmetro para o mรฉtodo โ€œpublic static String toString(int i)โ€ que retorna o especificador de acesso para a classe fornecida.

Como obter informaรงรตes completas sobre uma aula

Para obter informaรงรตes sobre variรกveisPara acessar os mรฉtodos e construtores de uma classe, precisamos criar um objeto dessa classe. O exemplo a seguir mostra diferentes maneiras de criar um objeto da classe "Classe":

Mรฉtodos usados โ€‹โ€‹em java.lang.Class

public class Guru99ClassObjectCreation {
    public static void main(String[] args) throws ClassNotFoundException {
        // 1 - By using Class.forName() method
        Class c1 = Class.forName("Guru99ClassObjectCreation");
        // 2 - By using getClass() method
        Guru99ClassObjectCreation guru99Obj = new Guru99ClassObjectCreation();
        Class c2 = guru99Obj.getClass();
        // 3 - By using .class
        Class c3 = Guru99ClassObjectCreation.class;
    }
}

Exemplo 1: Como obter os metadados de uma classe

O exemplo a seguir mostra como obter metadados como o nome da classe, o nome da superclasse, as interfaces implementadas e os modificadores de acesso de uma classe.

Obteremos os metadados da classe abaixo, com o nome especificado. Guru99Base.class:

Obtenha metadados da classe

import java.io.Serializable;
public abstract class Guru99Base implements Serializable, Cloneable {
}
  1. O nome da classe รฉ: Guru99Base
  2. Seus modificadores de acesso sรฃo: pรบblico e absoluto.tract
  3. Possui interfaces implementadas: Serializable e Cloneable
  4. Como nรฃo estende explicitamente nenhuma classe, sua superclasse รฉ: java.lang.Object

A classe abaixo obterรก os metadados de Guru99Base.class e imprima-o:

Obtenha metadados da classe

import java.lang.reflect.Modifier;
public class Guru99GetclassMetaData {
    public static void main(String[] args) throws ClassNotFoundException {
        // Create Class object for Guru99Base.class
        Class<Guru99Base> guru99ClassObj = Guru99Base.class;

        // Print name of the class
        System.out.println("Name of the class is : " + guru99ClassObj.getName());

        // Print super class name
        System.out.println("Name of the super class is : " + guru99ClassObj.getSuperclass().getName());

        // Get the list of implemented interfaces using getInterfaces() method
        Class[] guru99InterfaceList = guru99ClassObj.getInterfaces();

        // Print the implemented interfaces using a for-each loop
        System.out.print("Implemented interfaces are : ");
        for (Class guru99class1 : guru99InterfaceList) {
            System.out.print(guru99class1.getName() + " ");
        }
        System.out.println();

        // Get access modifiers using getModifiers() and Modifier.toString()
        int guru99AccessModifier = guru99ClassObj.getModifiers();
        System.out.println("Access modifiers of the class are : " + Modifier.toString(guru99AccessModifier));
    }
}
  1. Imprima o nome da classe usando o mรฉtodo getName().
  2. Imprima o nome da superclasse usando o mรฉtodo getSuperclass().getName().
  3. Imprima os nomes das interfaces implementadas.
  4. Imprima os modificadores de acesso usados โ€‹โ€‹pela classe.

Obtenha metadados da classe

Obtenha metadados da classe

Exemplo 2: Como obter os metadados de uma variรกvel

O exemplo a seguir mostra como obter os metadados de uma variรกvel.

Aqui, estamos criando uma classe chamada 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";
}

Etapas para obter os metadados sobre as variรกveis โ€‹โ€‹da classe acima:

  1. Crie o objeto da classe acima, ou seja, Guru99VariableMetaData.class, como abaixo:
    Guru99VariableMetaData guru99ClassVar = new Guru99VariableMetaData();
    Class guru99ClassObjVar = guru99ClassVar.getClass();
  2. Obtenha os metadados na forma de uma matriz de campos usando o getFields() or getDeclaredFields () mรฉtodos como abaixo:
    Field[] guru99Field1 = guru99ClassObjVar.getFields();
    Field[] guru99Field2 = guru99ClassObjVar.getDeclaredFields();

O getFields() O mรฉtodo retorna os metadados das variรกveis โ€‹โ€‹pรบblicas da classe especificada, bem como de sua superclasse.

O getDeclaredFields () O mรฉtodo retorna os metadados de todas as variรกveis โ€‹โ€‹apenas da classe especificada.

  1. Obtenha o nome das variรกveis โ€‹โ€‹usando o mรฉtodo โ€œpublic String getName()โ€.
  2. Obtenha o tipo de dados das variรกveis โ€‹โ€‹usando o mรฉtodo โ€œpublic Class getType()โ€.
  3. Obtenha o valor da variรกvel usando o mรฉtodo โ€œpublic xxx get(Field)โ€. Aqui, xxx pode ser um byte, um short ou qualquer tipo de valor que vocรช queira obter.
  4. Obtenha os modificadores de acesso das variรกveis โ€‹โ€‹usando os mรฉtodos getModifiers() e Modifier.toString(int i).

Aqui, estamos escrevendo uma classe para obter os metadados das variรกveis โ€‹โ€‹presentes na classe. Guru99VariableMetaData.class:

Obtenha metadados de variรกvel

package guru;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class Guru99VariableMetaDataTest {
    public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException {
        // Create Class object for Guru99VariableMetaData.class
        Guru99VariableMetaData guru99ClassVar = new Guru99VariableMetaData();
        Class guru99ClassObjVar = guru99ClassVar.getClass();

        // Get the metadata of all the fields of the class
        Field[] guru99Field1 = guru99ClassObjVar.getDeclaredFields();

        // Print name, data types, access modifiers and values of the variables
        for (Field field : guru99Field1) {
            System.out.println("Variable name : " + field.getName());
            System.out.println("Datatype of the variable : " + field.getType());

            int guru99AccessModifiers = field.getModifiers();
            System.out.println("Access Modifiers of the variable : " + Modifier.toString(guru99AccessModifiers));
            System.out.println("Value of the variable : " + field.get(guru99ClassVar));
            System.out.println();
        }
    }
}
  1. Criou-se um objeto de classe para Guru99VariableMetaData.class.
  2. Obtive todos os metadados das variรกveis โ€‹โ€‹em uma matriz de campos.
  3. Imprimiu todos os nomes de variรกveis โ€‹โ€‹da classe. Guru99VariableMetaData.class.
  4. Imprimiu todos os tipos de dados das variรกveis โ€‹โ€‹da classe.
  5. Imprimiu todos os modificadores de acesso das variรกveis โ€‹โ€‹da classe.
  6. Imprimiu os valores de todas as variรกveis โ€‹โ€‹da classe.

Obtenha metadados do mรฉtodo

Obtenha metadados do mรฉtodo

Exemplo 3: Como obter os metadados de um mรฉtodo

O exemplo a seguir mostra como obter os metadados de um mรฉtodo.

Aqui, estamos criando uma classe chamada Guru99MethodMetaData.class com alguns mรฉtodos:

Obtenha metadados do mรฉtodo

package guru;
import java.sql.SQLException;
public class Guru99MethodMetaData {

    public void guru99Add(int firstElement, int secondElement, String result)
    throws ClassNotFoundException, ClassCastException {
        System.out.println("Demo method for Reflection API");
    }
    public String guru99Search(String searchString)
    throws ArithmeticException, InterruptedException {
        System.out.println("Demo method for Reflection API");
        return null;
    }
    public void guru99Delete(String deleteString)
    throws SQLException {
        System.out.println("Demo method for Reflection API");
    }
}

Passos para obter os metadados sobre os mรฉtodos na classe acima:

  1. Crie o objeto da classe acima, ou seja, Guru99MethodMetaData.class, conforme abaixo:
    Guru99MethodMetaData guru99ClassVar = new Guru99MethodMetaData();
    Class guru99ClassObjVar = guru99ClassVar.getClass();
  2. Obtenha informaรงรตes sobre os mรฉtodos em um array de mรฉtodos usando os mรฉtodos getMethods() e getDeclaredMethods(), conforme abaixo:
    Method[] guru99Method1 = guru99ClassObjVar.getMethods();
    Method[] guru99Method2 = guru99ClassObjVar.getDeclaredMethods();

    O getMethods() O mรฉtodo retorna os metadados dos mรฉtodos pรบblicos da classe especificada, bem como de sua superclasse. getDeclaredMethods() O mรฉtodo retorna os metadados de todos os mรฉtodos da classe especificada.

  3. Obtenha o nome do mรฉtodo usando o getName () mรฉtodo.
  4. Obtenha o tipo de retorno do mรฉtodo usando o getReturnType() mรฉtodo.
  5. Obtenha os modificadores de acesso dos mรฉtodos usando o getModifiers() e Modificador.toString(int i) mรฉtodos.
  6. Obtenha os tipos de parรขmetros do mรฉtodo usando o getParameterTypes() mรฉtodo, que retorna um array de classes.
  7. Obtenha exceรงรตes lanรงadas usando o getExceptionTypes() mรฉtodo, que retorna um array de classes.

Aqui, estamos escrevendo uma classe para obter os metadados dos mรฉtodos presentes na classe. Guru99MethodMetaData.class:

Obtenha metadados do mรฉtodo

package guru;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class Guru99MethodMetaDataTest {

    public static void main(String[] args) {
        // Create Class object for Guru99MethodMetaData.class
        Class guru99ClassObj = Guru99MethodMetaData.class;

        // Get the metadata of all the methods using getDeclaredMethods()
        Method[] guru99Methods = guru99ClassObj.getDeclaredMethods();

        for (Method method : guru99Methods) {
            System.out.println("Name of the method : " + method.getName());
            System.out.println("Return type of the method : " + method.getReturnType());

            int guru99ModifierList = method.getModifiers();
            System.out.println("Method access modifiers : " + Modifier.toString(guru99ModifierList));

            Class[] guru99ParamList = method.getParameterTypes();
            System.out.print("Method parameter types : ");
            for (Class class1 : guru99ParamList) {
                System.out.print(class1.getName() + " ");
            }
            System.out.println();

            Class[] guru99ExceptionList = method.getExceptionTypes();
            System.out.print("Exception thrown by method : ");
            for (Class class1 : guru99ExceptionList) {
                System.out.print(class1.getName() + " ");
            }
            System.out.println();
        }
    }
}
  1. Criou-se um objeto de classe para Guru99MethodMetaData.class.
  2. Obtive todos os metadados de todos os mรฉtodos em uma matriz de mรฉtodos.
  3. Imprimiu todos os nomes de mรฉtodos presentes na classe.
  4. Imprimiu os tipos de retorno dos mรฉtodos da classe.
  5. Imprimiu todos os modificadores de acesso dos mรฉtodos da classe.
  6. Imprimiu os tipos de parรขmetros dos mรฉtodos.
  7. Imprimiu as exceรงรตes lanรงadas pelos mรฉtodos.

Obtenha metadados do mรฉtodo

Obtenha metadados do mรฉtodo

Exemplo 4: Como obter metadados de construtores

O exemplo a seguir mostra como obter os metadados dos construtores.

Aqui, estamos criando uma classe chamada Guru99Constructor.class com diferentes construtores:

Obtenha metadados de 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 name) throws RemoteException, SQLException { }
    public Guru99Constructor(int no, String name, String address) throws InterruptedException { }
}

Aqui, estamos escrevendo uma classe para obter os metadados dos construtores presentes na classe. Guru99Constructor.class:

Obtenha metadados de construtores

package guru;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
public class Guru99ConstructorMetaDataTest {

    public static void main(String[] args) {
        // Create Class object for Guru99Constructor.class
        Class guru99Class = Guru99Constructor.class;

        // Get all the constructor information in the Constructor array
        Constructor[] guru99ConstructorList = guru99Class.getConstructors();

        for (Constructor constructor : guru99ConstructorList) {
            System.out.println("Constructor name : " + constructor.getName());

            int guru99Modifiers = constructor.getModifiers();
            System.out.println("Constructor modifier : " + Modifier.toString(guru99Modifiers));

            Class[] guru99ParamList = constructor.getParameterTypes();
            System.out.print("Constructor parameter types : ");
            for (Class class1 : guru99ParamList) {
                System.out.print(class1.getName() + " ");
            }
            System.out.println();

            Class[] guru99ExceptionList = constructor.getExceptionTypes();
            System.out.print("Exception thrown by constructors : ");
            for (Class class1 : guru99ExceptionList) {
                System.out.print(class1.getName() + " ");
            }
            System.out.println();
        }
    }
}
  1. Criou-se um objeto de classe para Guru99Construtor.classe.
  2. Obtive todos os metadados de todos os construtores em um array de construtores.
  3. Imprimiu todos os nomes dos construtores presentes na classe.
  4. Imprimiu todos os modificadores de acesso dos construtores da classe.
  5. Imprimiu os tipos de parรขmetros dos construtores.
  6. Imprimiu as exceรงรตes lanรงadas pelos construtores.

Obtenha metadados de construtores

Obtenha metadados de construtores

Perguntas Frequentes

A reflexรฃo permite que frameworks e ferramentas de IA inspecionem e instanciem classes em tempo de execuรงรฃo. Ela viabiliza injeรงรฃo de dependรชncia, serializaรงรฃo e mapeamento ORM.pinge carregamento dinรขmico de plugins sem conhecer as classes exatas em tempo de compilaรงรฃo.

A IA pode gerar cรณdigo de reflexรฃo rapidamente, mas vocรช deve revisรก-lo cuidadosamente. A reflexรฃo pode ignorar verificaรงรตes de acesso e introduzir riscos de seguranรงa e desempenho, portanto, o cรณdigo gerado precisa ser testado e validado.

A reflexรฃo รฉ mais lenta do que chamadas de mรฉtodo diretas, pode quebrar o encapsulamento ao acessar membros privados e pode causar problemas de seguranรงa e manutenรงรฃo. Deve ser usada apenas quando nรฃo houver uma abordagem mais simples disponรญvel.

Sim. Usando `setAccessible(true)`, a reflexรฃo pode ler e modificar campos privados e invocar mรฉtodos privados. Isso รฉ poderoso para testes e frameworks, mas pode quebrar o encapsulamento e gerar problemas de seguranรงa.

Resuma esta postagem com: