¿Qué es Reflection en Java?
Java Reflection es el proceso de analizar y modificar todas las capacidades de una clase en tiempo de ejecución. La API de reflexión en Java se utiliza para manipular la clase y sus miembros, que incluyen campos, métodos, constructor, 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. Los métodos de la clase java.lang.Class se utilizan para recopilar los metadatos completos de una clase en particular.
En este tutorial, aprenderá:
- ¿Qué es la reflexión?
- Clase en el paquete java.lang.reflect
- Métodos utilizados en java.lang.Class
- Cómo obtener información completa sobre una clase
- Ejemplo 1: Cómo obtener metadatos de clase
- Ejemplo 2: Cómo obtener metadatos de variable
- Ejemplo 3: Cómo obtener metadatos del método
- Ejemplo 4: Cómo obtener metadatos de constructores
Clase en el paquete java.lang.reflect
A continuación se muestra 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 el modificador de acceso, el tipo de retorno, el nombre, los tipos de parámetros y el 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.
- Modificador : esta clase se utiliza para recopilar información sobre un modificador de acceso en particular.
Métodos utilizados en java.lang.Class
- Public String getName () : devuelve el nombre de la clase.
- public Class getSuperclass () : Devuelve la referencia de la superclase
- Public Class [] getInterfaces () : devuelve una matriz de interfaces implementadas por la clase especificada
- Public in getModifiers (): Devuelve un valor entero que representa los modificadores de la clase especificada que debe pasarse como parámetro al método " public static String toString (int i)" que devuelve el especificador de acceso para la clase dada.
Cómo obtener información completa sobre una clase
Para obtener información sobre variables, métodos y constructores de una clase, necesitamos crear un objeto de la clase.public class Guru99ClassObjectCreation {public static void main (String[] args) throws ClassNotFoundException {//1 - By using Class.forname() methodClass c1 = Class.forName("Guru99ClassObjectCreation");//2- By using getClass() methodGuru99ClassObjectCreation guru99Obj = new Guru99ClassObjectCreation();Class c2 = guru99Obj.getClass();//3- By using .classClass c3= Guru99ClassObjectCreation.class;}}
Ejemplo 1: Cómo obtener metadatos de clase
El siguiente 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:
import java.io.Serializable;public abstract class Guru99Base implements Serializable,Cloneable {}
- El nombre de la clase es: Guru99Base
- Sus modificadores de acceso son: público y abstracto
- Tiene interfaces implementadas: Serializable y Cloneable
- Dado que no ha extendido ninguna clase explícitamente, su superclase es: java.lang.Object
import java.lang.reflect.Modifier;public class Guru99GetclassMetaData {public static void main (String [] args) throws ClassNotFoundException {// Create Class object for Guru99Base.classClassguru99ClassObj = Guru99Base.class;// Print name of the classsystem.out.println("Name of the class is : " +guru99ClassObj.getName());// Print Super class namesystem.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() methodclass[] guru99InterfaceList = guru99classObj.getInterfaces();// Print the implemented interfaces using foreach loopsystem.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 classint guru99AccessModifier= guru99classObj.getModifiers();// Print the access modifiersSystem.Out.println("Access modifiers of the class are : " +Modifier.tostring(guru99AccessModifier));}}
- imprime el nombre de la clase usando el método getName
- Imprime el nombre de la superclase usando el método getSuperClass (). GetName ()
- Imprime el nombre de las interfaces implementadas
- Imprime los modificadores de acceso usados por la clase
Ejemplo 2: Cómo obtener metadatos de variable
Los siguientes ejemplos muestran cómo obtener metadatos de la 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:
- 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();
- Obtenga los metadatos en forma de matriz de campo utilizando los métodos getFields () o getDeclaredFields () como se muestra a continuación:
Field[] guru99Field1= guru99ClassObjVar .getFields();Field[] guru99Fiel2= guru99ClassObjVar .getDeclaredFields();
El método getFields () devuelve metadatos de la variable pública de la clase especificada, así como de su superclase.
El método getDeclaredFields () devuelve metadatos de todas las variables de la clase especificada únicamente.
- Obtenga el nombre de las variables usando el método "public String getName ()".
- Obtenga el tipo de datos de las variables usando el método "public Class getType ()".
- Obtenga el valor de la variable usando el método "public xxx get (Field)".
Aquí, xxx podría ser un byte o una cantidad corta de cualquier tipo de valor que queramos obtener.
- Obtenga los modificadores de acceso de las variables mediante 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:
package guru;import java.lang.reflect.Field;public class Guru99VariableMetaDataTest {public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException {// Create Class object for Guru99VariableMetaData.classGuru99VariableMetaData guru99ClassVar = new Guru99VariableMetaData();Class guru99ClassObjVar = guru99ClassVar.getClass();// Get the metadata of all the fields of the class Guru99VariableMetaDataField[] guru99Field1= guru99ClassObjVar.getDeclaredFields();// Print name, datatypes, access modifiers and values of the varibales of the specified classfor(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("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *") ;}}}
- Objeto de clase creado para Guru99VariableMetaData.class
- Obtuve todos los metadatos de las variables en una matriz de campo
- Imprimió todos los nombres de las variables en la clase Guru99VariableMetaData.class
- Imprimió todos los tipos de datos de las variables en la clase Guru99VariableMetaData.class
- Imprimió todos los modificadores de acceso de las variables en la clase Guru99VariableMetaData.class
- Valores impresos de todas las variables en Impreso todos los tipos de datos de las variables en la clase Guru99VariableMetaData.class
- 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();
- Obtenga información sobre el 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();
El método getMethods () devuelve metadatos de los métodos públicos de la clase especificada, así como de su superclase.
El método getDeclaredMethods () devuelve metadatos de todos los métodos de la clase especificada únicamente.
- Obtenga el nombre del método usando el método getName () .
- Obtenga el tipo de retorno del método usando el método getReturnType () .
- Obtenga modificadores de acceso de los métodos mediante los métodos getModifiers () y Modifiers.toString (int i) .
- Obtenga los tipos de parámetros de método usando el método getParameterTypes () que devuelve una matriz de clases.
- Obtenga una excepción lanzada usando el método getExceptionTypes () que devuelve una matriz de clases.
- Objeto de clase creado para Guru99MethodMetaData.class
- Obtuve todos los metadatos de todos los métodos en una matriz de métodos
- Imprimió todos los nombres de métodos presentes en la clase Guru99MethodMetaData.class
- Tipos de devolución impresos de los métodos de la clase Guru99MethodMetaData.class
- Imprimió todos los modificadores de acceso de los métodos en la clase Guru99MethodMetaData.class
- Tipos de parámetros impresos de los métodos en Guru99MethodMetaData.class
- Las excepciones impresas son lanzadas por métodos en Guru99MethodMetaData.class
- Objeto de clase creado para Guru99Constructor.class
- Obtuve todos los metadatos de todos los constructores en una matriz de constructores
- Imprimió todos los nombres de los constructores presentes en la clase Guru99Constructor.class
- Imprimió todos los modificadores de acceso de los constructores en la clase Guru99Constructor.class
- Tipos de parámetros impresos de los constructores en Guru99Constructor.class
- Los constructores lanzan excepciones impresas en Guru99Constructor.class
- La programación de reflexión en Java ayuda a recuperar y modificar información sobre las clases y los miembros de la clase, tales como variables, métodos y constructores.
- La API Reflection en Java se puede implementar usando clases en el paquete java.lang.reflect y métodos de la clase java.lang.Class.
- Algunos métodos de uso común de la clase java.lang.Class son getName (), getSuperclass (), getInterfaces (), getModifiers (), etc.
- Algunas clases de uso común en el paquete java.lang.reflect son Field, Method, Constructor, Modifier, etc.
- Reflection API puede acceder a métodos privados y variables de una clase que podrían ser 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.
Ejemplo 3: Cómo obtener metadatos del método
Los siguientes ejemplos muestran cómo obtener metadatos de un método:
Aquí, estamos creando una clase llamada Guru99MethodMetaData .class con algunos métodos
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:
Aquí, estamos escribiendo una clase para obtener los metadatos de los métodos presentes en la clase Guru99MethodMetaData.class:
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.classclass 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 namesSystem.out.println("Name of the method : "+method.getName());// Print return type of the methodsSystem.out.println("Return type of the method : "+method.getReturnType());//Get the access modifier list and printint guru99ModifierList = method.getModifiers();System.Out.printlin ("Method access modifiers : "+Modifier.toString(guru99ModifierList));// Get and print parameters of the methodsClass[] 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 methodClass[] 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("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ");}}}
Ejemplo 4: Cómo obtener metadatos de constructores
Los siguientes ejemplos muestran cómo obtener metadatos de constructores:
Aquí, estamos creando una clase llamada Guru99Constructor.class con diferentes 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:
package guru;import java.lang.reflect.Constructor;public class Guru99ConstructorMetaDataTest {public static void main (String[] args) {// Create Class object for Guru99Constructor.classClass guru99Class=Guru99Constructor.class;// Get all the constructor information in the Constructor arrayConstructor[] guru99ConstructorList = guru99Class.getConstructors();for (Constructor constructor : guru99ConstructorList) {// Print all name of each constructorSystem.out.println("Constrcutor name : "+constructor.getName());//Get and print access modifiers of each constructorint guru99Modifiers= constructor.getModifiers();System.Out.printlin ("Constrctor modifier : "+Modifier.toString(guru99Modifiers));// Get and print parameter typesClass[] 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 constructorsClass[] 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("*******************************************");}}}
Resumen: