Tutorial de la API Java Reflection con ejemplo

¿Qué es la reflexión en Java?

Java Reflection es el proceso de analizar y modificar todas las capacidades de una clase en tiempo de ejecución. La API Reflection en Java se utiliza para manipular clases y sus miembros que incluyen campos, métodos, constructores, etc. en tiempo de ejecución.

Una ventaja de la API de reflexión en Java es que también puede manipular miembros privados de la clase.

El paquete java.lang.reflect proporciona muchas clases para implementar la reflexión java. Los métodos de la clase java.lang.Class se utilizan para recopilar los metadatos completos de una clase en particular.

Clase en el paquete java.lang.reflect

Following es una lista de varias clases de Java en java.lang.package para implementar la reflexión-

  • Campo: Esta clase se utiliza para recopilar información declarativa como tipo de datos, modificador de acceso, nombre y valor de una variable.
  • Método: esta clase se utiliza para recopilar información declarativa como modificador de acceso, tipo de retorno, nombre, tipos de parámetros y tipo de excepción de un método.
  • Constructor: Esta clase se utiliza para recopilar información declarativa como el modificador de acceso, el nombre y los tipos de parámetros de un constructor.
  • Cambiar: esta clase se utiliza para recopilar información sobre un modificador de acceso en particular.

Métodos utilizados en java.lang.Class

  • Cadena pública getName (): Devuelve el nombre de la clase.
  • Clase pública getSuperclass(): Devuelve la referencia de la superclase
  • Clase pública[] getInterfaces() : Devuelve una matriz de interfaces implementadas por la clase especificada
  • Público en getModifiers (): Devuelve un valor entero que representa los modificadores de la clase especificada que debe pasarse como parámetro a "cadena estática pública a cadena (int i)” Método que devuelve el especificador de acceso para la clase dada.

Cómo obtener información completa sobre una clase

Para obtener información sobre las variables, métodos y constructores de una clase, necesitamos crear un objeto de la clase.

Métodos utilizados en 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;
		}
	}
  • Following El ejemplo muestra diferentes formas de crear un objeto de clase “clase”:
  • Ejemplo 1: Cómo obtener metadatos de clase

    Following El ejemplo muestra cómo obtener metadatos como: nombre de clase, nombre de superclase, interfaces implementadas y modificadores de acceso de una clase.

    Obtendremos los metadatos de la siguiente clase llamada Guru99Base.class:

    Obtener metadatos de clase

    import java.io.Serializable;
    public abstract class Guru99Base implements Serializable,Cloneable {
    }
    
    1. El nombre de la clase es: Guru99Base
    2. Sus modificadores de acceso son: público y abstracto.
    3. Tiene interfaces implementadas: Serializable y Clonable.
    4. Como no ha extendido ninguna clase explícitamente, su superclase es: java.lang.Object

    La siguiente clase obtendrá los metadatos de Guru99Base.class y los imprimirá:

    Obtener metadatos de clase

    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. imprime el nombre de la clase usando el método getName
    2. Imprima el nombre de la superclase usando el método getSuperClass().getName()
    3. Imprimir el nombre de las interfaces implementadas.
    4. Imprime los modificadores de acceso utilizados por la clase.

    Obtener metadatos de clase

    Obtener metadatos de clase

    Ejemplo 2: Cómo obtener metadatos de variable

    Following Los ejemplos muestran cómo obtener metadatos de una variable:

    Aquí, estamos creando una clase llamada Guru99VariableMetaData .class con algunas variables:

    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";    
    }	
    
    Pasos para obtener los metadatos sobre las variables de la clase anterior:
    1. Cree el objeto de clase de la clase anterior, es decir, Guru99VariableMetaData.class como se muestra a continuación:
        Guru99VariableMetaData  guru99ClassVar  = new Guru99VariableMetaData();
        Class  guru99ClassObjVar  = guru99ClassVar.getClass();
    2. Obtenga los metadatos en forma de matriz de campos usando getFields () or obtenerCamposDeclarados() métodos de la siguiente manera:
      Field[]  guru99Field1= guru99ClassObjVar .getFields();
      Field[]  guru99Fiel2= guru99ClassObjVar .getDeclaredFields();

    getFields () El método devuelve metadatos de la variable pública de la clase especificada, así como de su superclase.

    obtenerCamposDeclarados() El método devuelve metadatos de todas las variables de la clase especificada únicamente.

    1. Obtenga el nombre de las variables utilizando el método “public String getName()”.
    2. Obtenga el tipo de datos de las variables utilizando el método “clase pública getType()”.
    3. Obtenga el valor de la variable utilizando el método "public xxx get (campo)".

      Aquí, xxx podría ser un byte o menos de cualquier tipo de valor que queramos recuperar.

    4. Obtenga los modificadores de acceso de las variables utilizando los métodos getModifier() y Modifier.toString(int i).

      Aquí, estamos escribiendo una clase para obtener los metadatos de las variables presentes en la clase Guru99VariableMetaData .class:

      Obtener metadatos de variable

      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 clase creado para Guru99VariableMetaData.class
      2. Obtuve todos los metadatos de las variables en una matriz de campo.
      3. Imprimí todos los nombres de variables en la clase Guru99VariableMetaData.class
      4. Imprimí todos los tipos de datos de las variables en la clase Guru99VariableMetaData.class
      5. Imprimieron todos los modificadores de acceso de las variables en la clase Guru99VariableMetaData.class
      6. Valores impresos de todas las variables en Impresos todos los tipos de datos de las variables en la clase Guru99VariableMetaData.class

      Obtener metadatos del método

      Obtener metadatos del método

      Ejemplo 3: Cómo obtener metadatos del método

      Following Los ejemplos muestran cómo obtener metadatos de un método:

      Aquí, estamos creando una clase llamada Guru99MethodMetaData .class con algunos métodos

      Obtener metadatos del 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");					
          }	
      }

      Pasos para obtener los metadatos sobre los métodos de la clase anterior:

      1. Cree el objeto de clase de la clase anterior, es decir, Guru99MethodMetaData.class como se muestra a continuación:
        Guru99MethodMetaData  guru99ClassVar  = new Guru99MethodMetaData  ();
        Class  guru99ClassObjVar  = guru99ClassVar.getClass();
      2. Obtenga información del método en una matriz de métodos utilizando los métodos getMethods() y getDeclaredMethods() como se muestra a continuación:
        Method[]  guru99 Method 1= guru99ClassObjVar .get Methods();
        Method []  guru99 Method 2= guru99ClassObjVar .getDeclared Method s();

        obtener métodos() El método devuelve metadatos de los métodos públicos de la clase especificada, así como de su superclase.

        obtener métodos declarados () El método devuelve metadatos de todos los métodos de la clase especificada únicamente.

      3. Obtenga el nombre del método usando getName () método.
      4. Obtenga el tipo de retorno del método usando getReturnType() método.
      5. Obtener modificadores de acceso de los métodos usando getModifiers () y Modificadores.toString(int i) métodos.
      6. Obtener tipos de parámetros de método usando getParameterTypes () método que devuelve una matriz de clases.
      7. Obtener una excepción usando obtener tipos de excepción() método que devuelve una matriz de clases.

      Aquí, estamos escribiendo una clase para obtener los metadatos de los métodos presentes en la clase Guru99MethodMetaData.class:

      Obtener metadatos del 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 clase creado para Guru99MethodMetaData.class
      2. Obtuve todos los metadatos de todos los métodos en una matriz de métodos.
      3. Imprimí todos los nombres de métodos presentes en la clase Guru99MethodMetaData.class
      4. Tipos de retorno impresos de los métodos de la clase Guru99MethodMetaData.class
      5. Imprimieron todos los modificadores de acceso de los métodos de la clase Guru99MethodMetaData.class
      6. Tipos de parámetros impresos de los métodos en Guru99MethodMetaData.class
      7. Las excepciones impresas son generadas por métodos en Guru99MethodMetaData.class

        Obtener metadatos del método

      Obtener metadatos del método

      Ejemplo 4: Cómo obtener metadatos de constructores

      Following Los ejemplos muestran cómo obtener metadatos de constructores:

      Aquí, estamos creando una clase llamada Guru99Constructor.class con diferentes constructores:

      Obtener metadatos de constructores

      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{  }							
      }

      Aquí, estamos escribiendo una clase para obtener los metadatos de los constructores presentes en la clase Guru99Constructor.class:

      Obtener metadatos de constructores

      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 clase creado para Guru99Constructor.class
      2. Obtuve todos los metadatos de todos los constructores en una matriz de constructores.
      3. Imprimieron todos los nombres de los constructores presentes en la clase Guru99Constructor.class
      4. Imprimieron todos los modificadores de acceso de los constructores en la clase Guru99Constructor.class
      5. Tipos de parámetros impresos de los constructores en Guru99Constructor.class
      6. Los constructores lanzan excepciones impresas en Guru99Constructor.class

      Obtener metadatos de constructores

      Obtener metadatos de constructores

      Resumen

      • La programación de reflexión en Java ayuda a recuperar y modificar información sobre las clases y los miembros de la clase, como variables, métodos y constructores.
      • La API Reflection en Java se puede implementar utilizando clases en el paquete java.lang.reflect y métodos de la clase java.lang.Class.
      • Algunos métodos comúnmente utilizados de la clase java.lang.Class son getName (), getSuperclass (), getInterfaces (), getModifiers (), etc.
      • Algunas clases comúnmente utilizadas en el paquete java.lang.reflect son Campo, Método, Constructor, Modificador, etc.
      • La API de Reflection puede acceder a métodos privados y variables de una clase que podrían representar una amenaza para la seguridad.
      • Reflection API es una capacidad poderosa proporcionada por Java, pero viene con algunos gastos generales, como un rendimiento más lento, vulnerabilidad de seguridad y problemas de permisos. Por lo tanto, la API de reflexión debe tratarse como el último recurso para realizar una operación.