Java Tutorial da API Reflection com exemplo

O que รฉ reflexรฃo Java?

Java Reflexรฃo รฉ o processo de analisar e modificar todos os recursos de uma classe em tempo de execuรงรฃo. API de reflexรฃo em Java รฉ usado para manipular classes e seus membros que incluem campos, mรฉtodos, construtor, etc. em tempo de execuรงรฃo.

Uma vantagem da API de reflexรฃo em Java isto รฉ, ele tambรฉm pode manipular membros privados da classe.

O pacote java.lang.reflect fornece muitas classes para implementar a reflexรฃo java.Methods da classe java.lang.Class รฉ usado para reunir os metadados completos de uma classe especรญfica.

Classe no pacote java.lang.reflect

Segue uma lista de vรกrio Java aulas em java.lang.package para implementar reflexรฃo-

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

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

  • String pรบblica getNome(): Retorna o nome da classe.
  • Classe pรบblica getSuperclass(): Retorna a referรชncia da superclasse
  • Classe pรบblica[] getInterfaces() : Retorna um array de interfaces implementadas pela classe especificada
  • Pรบblico em getModifiers(): Retorna um valor inteiro representando os modificadores da classe especificada que precisa ser passado como parรขmetro para โ€œString estรกtica pรบblica paraString (int i)โ€ mรฉtodo que retorna o especificador de acesso para a classe fornecida.

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

Para obter informaรงรตes sobre variรกveis, mรฉtodos e construtores de uma classe, precisamos criar um objeto da 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;
		}
	}
  • O exemplo a seguir mostra diferentes maneiras de criar o objeto da classe โ€œclassโ€:
  • Exemplo 1: Como obter metadados de classe

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

    Obteremos os metadados da classe abaixo chamada 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 abstrato
    3. Possui interfaces implementadas: Serializable e Cloneable
    4. Como nรฃo estendeu nenhuma classe explicitamente, sua superclasse รฉ: java.lang.Object

    A classe abaixo obterรก os metadados de Guru99Base.class e os imprimirรก:

    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 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 in the form of Class array using getInterface() method
    	class[] guru99InterfaceList = guru99classObj.getInterfaces();
    	
    	// Print the implemented interfaces using foreach loop 
    	system.out.print("Implemented interfaces are : ");
    	for (Class guru99class1 : quru99 InterfaceList)	{
    		system.out.print guru99class1.getName() + " ");
    	}
    	system.out.println();
    	
    	//Get access modifiers using get Modifiers() method and toString() method of java.lang.reflect.Modifier class
    	int guru99AccessModifier= guru99classObj.getModifiers(); 
    	// Print the access modifiers
    	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 o nome das interfaces implementadas
    4. Imprima os modificadores de acesso usados โ€‹โ€‹pela classe

    Obtenha metadados da classe

    Obtenha metadados da classe

    Exemplo 2: Como obter metadados de variรกvel

    Os exemplos a seguir mostram como obter metadados de variรกveis:

    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 de classe da classe acima, ou seja, Guru99VariableMetaData.class conforme abaixo:
        Guru99VariableMetaData  guru99ClassVar  = new Guru99VariableMetaData();
        Class  guru99ClassObjVar  = guru99ClassVar.getClass();
    2. Obtenha os metadados na forma de array de campos usando getFields() or getDeclaredFields () mรฉtodos como abaixo:
      Field[]  guru99Field1= guru99ClassObjVar .getFields();
      Field[]  guru99Fiel2= guru99ClassObjVar .getDeclaredFields();

    getFields() O mรฉtodo retorna metadados da variรกvel pรบblica da classe especificada, bem como de sua superclasse.

    getDeclaredFields () O mรฉtodo retorna 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 ou menos de qualquer tipo de valor que desejamos buscar.

    4. Obtenha os modificadores de acesso das variรกveis โ€‹โ€‹usando os mรฉtodos getModifier() 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; 
      
      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 Guru99VariableMetaData 
      	Field[] guru99Field1= guru99ClassObjVar.getDeclaredFields();
      	
      	// Print name, datatypes, access modifiers and values of the varibales of the specified class 
      	for(Field field : guru99Field1) { 
      	System.out.println("Variable name : "+field.getName());
      	System.out.println("Datatypes of the variable :"+field.getType());
      	
      	int guru99AccessModifiers = field.getModifiers();
      	System.out.printlln("Access Modifiers of the variable : "+Modifier.toString(guru99AccessModifiers));
      	System.out.println("Value of the variable : "+field.get(guru99ClassVar));
      	System.out.println();
      	system.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *") ;
      	}
      	}
      }
      
      1. Objeto de classe criado para Guru99VariableMetaData.class
      2. Obteve todos os metadados das variรกveis โ€‹โ€‹em uma matriz Field
      3. Imprimiu todos os nomes de variรกveis โ€‹โ€‹na classe Guru99VariableMetaData.class
      4. Imprimiu todos os tipos de dados das variรกveis โ€‹โ€‹na classe Guru99VariableMetaData.class
      5. Imprimiu todos os modificadores de acesso das variรกveis โ€‹โ€‹da classe Guru99VariableMetaData.class
      6. Valores impressos de todas as variรกveis โ€‹โ€‹em Impressos todos os tipos de dados das variรกveis โ€‹โ€‹na classe Guru99VariableMetaData.class

      Obtenha metadados do mรฉtodo

      Obtenha metadados do mรฉtodo

      Exemplo 3: Como obter metadados do mรฉtodo

      Os exemplos a seguir mostram como obter 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 Reflextion  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");					
          }	
      }

      Etapas para obter os metadados sobre os mรฉtodos da classe acima:

      1. Crie o objeto de classe da classe acima, ou seja, Guru99MethodMetaData.class conforme abaixo:
        Guru99MethodMetaData  guru99ClassVar  = new Guru99MethodMetaData  ();
        Class  guru99ClassObjVar  = guru99ClassVar.getClass();
      2. Obtenha informaรงรตes do mรฉtodo em uma matriz de mรฉtodo usando os mรฉtodos getMethods() e getDeclaredMethods() conforme abaixo:
        Method[]  guru99 Method 1= guru99ClassObjVar .get Methods();
        Method []  guru99 Method 2= guru99ClassObjVar .getDeclared Method s();

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

        getDeclaredMethods() O mรฉtodo retorna metadados de todos os mรฉtodos apenas da classe especificada.

      3. Obtenha o nome do mรฉtodo usando getName () mรฉtodo.
      4. Obtenha o tipo de retorno do mรฉtodo usando getReturnType() mรฉtodo.
      5. Obtenha modificadores de acesso dos mรฉtodos usando getModifiers() e Modificadores.toString(int i) mรฉtodos.
      6. Obtenha tipos de parรขmetros de mรฉtodo usando getParameterTypes() mรฉtodo que retorna um array de classe.
      7. Obtenha uma exceรงรฃo lanรงada usando getExceptionTypes() mรฉtodo que retorna um array de classe.

      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 Guru99Method MetaData.class 
      		class guru99ClassObj = Guru99MethodMetaData.class;
      
      		// Get the metadata or information of all the methods of the class using getDeclaredMethods() 
      		Method[] guru99Methods=guru99classObj.getDeclaredMethods();
      
      		for(Method method : guru99Methods) { 
      		// Print the method names
      		System.out.println("Name of the method : "+method.getName());
      		
      		// Print return type of the methods 
      		System.out.println("Return type of the method : "+method.getReturnType());
      		
      		//Get the access modifier list and print
      		int guru99ModifierList = method.getModifiers(); 
      		System.Out.printlin ("Method access modifiers : "+Modifier.toString(guru99ModifierList));
      		
      		// Get and print parameters of the methods 
      		Class[] guru99ParamList= method.getParameterTypes(); 
      		system.out.print ("Method parameter types : "); 
      		for (Class class1 : guru99ParamList){ 
      			System.out.println(class1.getName()+" ");
      		}
              System.out.println();
      		
      		// Get and print exception thrown by the method 
      		Class[] guru99ExceptionList = method. getExceptionTypes(); 
      		system.out.print("Excpetion thrown by method :"); 
      		for (Class class1 : guru99ExceptionList) {
      			System.out.println (class1.getName() +" "):
      		} 
      		System.Out.println(); 
      		system.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ");
      		
      		}
       
      	}
      }
      
      1. Objeto de classe criado para Guru99MethodMetaData.class
      2. Obteve todos os metadados de todos os mรฉtodos em uma matriz de mรฉtodos
      3. Impresso todos os nomes de mรฉtodos presentes na classe Guru99MethodMetaData.class
      4. Tipos de retorno impressos dos mรฉtodos da classe Guru99MethodMetaData.class
      5. Imprimiu todos os modificadores de acesso dos mรฉtodos da classe Guru99MethodMetaData.class
      6. Tipos de parรขmetros impressos dos mรฉtodos em Guru99MethodMetaData.class
      7. Exceรงรตes impressas sรฃo lanรงadas por mรฉtodos em Guru99MethodMetaData.class

        Obtenha metadados do mรฉtodo

      Obtenha metadados do mรฉtodo

      Exemplo 4: Como obter metadados de construtores

      Os exemplos a seguir mostram como obter metadados de 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; 
      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) {
      			// Print all name of each constructor
      			System.out.println("Constrcutor name : "+constructor.getName());
      			
      			//Get and print access modifiers of each constructor 
      			int guru99Modifiers= constructor.getModifiers(); 
      			System.Out.printlin ("Constrctor modifier : "+Modifier.toString(guru99Modifiers));
      			
      			// Get and print parameter types 
      			Class[] guru99ParamList=constructor.getParameterTypes();
      			System.out.print ("Constrctor parameter types :"); 
      			for (Class class1 : guru99ParamList) { 
      				System.out.println(class1.getName() +" ");
      			}
      			System. out.println();
      
      			// Get and print exception thrown by constructors
      			Class[] guru99ExceptionList=constructor.getFxceptionTypes();
      			System.out.println("Exception thrown by constructors :"); 
      			for (Class class1 : guru99ExceptionList) { 
      				System.out.println(class1.getName() +" ");
      			} 
      			System.out.println();
      			System.out.println("*******************************************");
      		}
      	}
      }
      
      1. Objeto de classe criado para Guru99Constructor.class
      2. Obteve todos os metadados de todos os construtores em uma matriz de construtores
      3. Imprimiu todos os nomes dos construtores presentes na classe Guru99Constructor.class
      4. Imprimiu todos os modificadores de acesso dos construtores na classe Guru99Constructor.class
      5. Tipos de parรขmetros impressos dos construtores em Guru99Constructor.class
      6. Exceรงรตes impressas sรฃo lanรงadas por construtores em Guru99Constructor.class

      Obtenha metadados de construtores

      Obtenha metadados de construtores

      Resumo

      • A programaรงรฃo de reflexรฃo em java ajuda a recuperar e modificar informaรงรตes sobre classes e membros de classes, como variรกveis, mรฉtodos e construtores.
      • API de reflexรฃo em Java pode ser implementado usando classes no pacote java.lang.reflect e mรฉtodos da classe java.lang.Class.
      • Alguns mรฉtodos comumente usados โ€‹โ€‹โ€‹โ€‹da classe java.lang.Class sรฃo getName (), getSuperclass (), getInterfaces (), getModifiers () etc.
      • Algumas classes comumente usadas no pacote java.lang.reflect sรฃo Campo, Mรฉtodo, Construtor, Modificador, etc.
      • A API Reflection pode acessar mรฉtodos e variรกveis โ€‹โ€‹privadas de uma classe que pode ser uma ameaรงa ร  seguranรงa.
      • A API Reflection รฉ um recurso poderoso fornecido por Java, mas vem com algumas sobrecargas, como desempenho mais lento, vulnerabilidade de seguranรงa e problema de permissรฃo. Portanto, a API de reflexรฃo deve ser tratada como o รบltimo recurso para executar uma operaรงรฃo.

    Resuma esta postagem com: