带有示例的 Java 反射 API 教程
什么是 Java 中的反射?
Java 反射是在运行时分析和修改类的所有功能的过程。 Java中的反射API用于在运行时操作类及其成员,包括字段、方法、构造函数等。
Java中反射API的一个优点是,它也可以操作类的私有成员。
java.lang.reflect 包提供了很多类来实现反射 java.lang.Class 类的 java.Methods 用于收集特定类的完整元数据。
在本教程中,您将学习-
- 什么是反射
- java.lang.reflect 包中的类
- java.lang.Class 中使用的方法
- 如何获取有关课程的完整信息
- 示例一:如何获取类的元数据
- 示例 2:如何获取变量的元数据
- 示例 3:如何获取方法的元数据
- 示例 4:如何获取构造函数的元数据
java.lang.reflect 包中的类
以下是java.lang.package中实现反射的各种Java类的列表-
- 字段 :此类用于收集声明性信息,例如数据类型、访问修饰符、变量的名称和值。
- 方法 :该类用于收集方法的访问修饰符、返回类型、名称、参数类型和异常类型等声明性信息。
- 构造函数 :该类用于收集声明性信息,例如构造函数的访问修饰符、名称和参数类型。
- 修饰符 :此类用于收集有关特定访问修饰符的信息。
java.lang.Class中使用的方法
- 公共字符串getName() :返回类的名称。
- 公共类 getSuperclass() :返回超类引用
- 公共类[] getInterfaces() :返回指定类实现的接口数组
- 在getModifiers()中公开: 返回一个整数值,表示指定类的修饰符,该修饰符需要作为参数传递给“public static String toString (int i)” 返回给定类的访问说明符的方法。
如何获取有关课程的完整信息
要获取有关类的变量、方法和构造函数的信息,我们需要创建该类的对象。
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;
}
}
示例1:如何获取类的元数据
以下示例展示了如何获取元数据,例如:类名、超类名、实现的接口和类的访问修饰符。
我们将获得以下名为 Guru99Base.class 的类的元数据:
import java.io.Serializable;
public abstract class Guru99Base implements Serializable,Cloneable {
}
- 班级名称:Guru99Base
- 它的访问修饰符是:public 和 abstract
- 实现了接口:Serializable 和 Cloneable
- 由于它没有显式扩展任何类,它的超类是:java.lang.Object
下面的class会获取Guru99Base.class的元数据并打印出来:
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));
}
}
- 使用 getName 方法打印类的名称
- 使用 getSuperClass().getName() 方法打印超类的名称
- 打印实现的接口的名称
- 打印类使用的访问修饰符
示例 2:如何获取变量的元数据
以下示例展示了如何获取变量的元数据:
在这里,我们创建了一个名为 Guru99VariableMetaData .class 的类,其中包含一些变量:
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";
}
获取上述类中变量元数据的步骤: - 创建上述类的类对象,即 Guru99VariableMetaData.class 如下:
Guru99VariableMetaData guru99ClassVar = new Guru99VariableMetaData(); Class guru99ClassObjVar = guru99ClassVar.getClass();
- 使用getFields()获取字段数组形式的元数据 或 getDeclaredFields() 方法如下:
Field[] guru99Field1= guru99ClassObjVar .getFields(); Field[] guru99Fiel2= guru99ClassObjVar .getDeclaredFields();
getFields() 方法从指定类及其超类返回公共变量的元数据。
getDeclaredFields() 方法只返回指定类中所有变量的元数据。
- 使用“public String getName()”方法获取变量名。
- 使用“public Class getType()”方法获取变量的数据类型。
- 使用“public xxx get(Field)”方法获取变量的值。
在这里,xxx 可以是一个字节,也可以是我们想要获取的任何类型的值。
- 使用 getModifier() 和 Modifier.toString(int i) 方法获取变量的访问修饰符。
在这里,我们正在编写一个类来获取 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.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("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *") ; } } } - 为 Guru99VariableMetaData.class 创建类对象
- 获取 Field 数组中变量的所有元数据
- 打印 Guru99VariableMetaData.class 类中的所有变量名
- 打印Guru99VariableMetaData.class类中变量的所有数据类型
- 打印 Guru99VariableMetaData.class 类中变量的所有访问修饰符
- 打印Guru99VariableMetaData.class类中所有变量的所有数据类型
- 创建上述类的类对象,即Guru99MethodMetaData.class如下:
Guru99MethodMetaData guru99ClassVar = new Guru99MethodMetaData (); Class guru99ClassObjVar = guru99ClassVar.getClass();
- 使用 getMethods() 和 getDeclaredMethods() 方法获取 Method 数组中的方法信息,如下所示:
Method[] guru99 Method 1= guru99ClassObjVar .get Methods(); Method [] guru99 Method 2= guru99ClassObjVar .getDeclared Method s();
getMethods() 方法从指定类及其超类返回公共方法的元数据。
getDeclaredMethods() 方法仅返回指定类中所有方法的元数据。
- 使用 getName() 获取方法名 方法。
- 使用 getReturnType() 获取方法的返回类型 方法。
- 使用 getModifiers() 获取方法的访问修饰符 and Modifiers.toString(int i) 方法。
- 使用getParameterTypes()获取方法参数类型 返回类数组的方法。
- 使用 getExceptionTypes() 获取抛出的异常 返回类数组的方法。
- 为 Guru99MethodMetaData.class 创建类对象
- 获取 Method 数组中所有方法的所有元数据
- 打印 Guru99MethodMetaData.class 类中存在的所有方法名称
- Guru99MethodMetaData.class 类中方法的打印返回类型
- 打印 Guru99MethodMetaData.class 类中方法的所有访问修饰符
- Guru99MethodMetaData.class 中方法的打印参数类型
- 打印的异常由 Guru99MethodMetaData.class 中的方法抛出
- 为 Guru99Constructor.class 创建类对象
- 获取构造函数数组中所有构造函数的所有元数据
- 打印 Guru99Constructor.class 中存在的所有构造函数的名称
- 打印类 Guru99Constructor.class 中构造函数的所有访问修饰符
- Guru99Constructor.class 中构造函数的打印参数类型
- Guru99Constructor.class 中的构造函数会抛出打印的异常
- Java 中的反射编程有助于检索和修改有关类和类成员(例如变量、方法、构造函数)的信息。
- Java 中的反射 API 可以使用 java.lang.reflect 包中的类和 java.lang.Class 类的方法来实现。
- java.lang.Class类的一些常用方法有getName()、getSuperclass()、getInterfaces()、getModifiers()等。
- java.lang.reflect包中一些常用的类有Field、Method、Constructor、Modifier等。
- 反射 API 可以访问可能构成安全威胁的类的私有方法和变量。
- Reflection API 是 Java 提供的一项强大功能,但它带来了一些开销,例如性能较慢、安全漏洞和权限问题。因此,反射 API 应被视为执行操作的最后手段。
示例 3:如何获取方法的元数据
以下示例展示了如何获取方法的元数据:
在这里,我们正在创建一个名为 Guru99MethodMetaData .class 的类,其中包含一些方法
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");
}
} 获取有关上述类中方法的元数据的步骤:
在这里,我们正在编写一个类来获取 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.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("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ");
}
}
}
示例 4:如何获取构造函数的元数据
以下示例展示了如何获取构造函数的元数据:
在这里,我们正在创建一个名为 Guru99Constructor.class 的类,其中包含不同的构造函数:
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{ }
} 在这里,我们正在编写一个类来获取 Guru99Constructor.class 中存在的构造函数的元数据:
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("*******************************************");
}
}
}
总结:
java