Java 中的 reflection 是什么
本文介绍 reflection 以及如何在 Java 中使用它。Java 有一个 reflection API 特性,它允许我们检查和修改类、接口等。
在本文中,我们将了解什么是 reflection API 及其用途。Java 中的 reflection 允许我们在运行时观察和更改类、接口、构造函数、方法和字段,即使我们在编译时不知道类名。
创建新对象、调用方法和获取/设置字段值都可以通过 reflection 完成。让我们通过一些例子来理解。
我们首先需要导入以下包来使用 reflection API。
java.lang.reflect.*
它导入 reflection API 中包含的所有类。
类对象
导入包后,我们需要创建一个类对象来使用 reflection API 方法。
类存在于 Java 中,因为它在运行时跟踪有关对象和类的所有数据。reflection 可以在 Class 对象上执行。
可以通过三种方式创建类对象。我们将逐一研究每种方法。
但在此之前,让我们创建一个将在本教程中使用的类。
class Furniture {
public String name;
private int price;
public Furniture(String name, int price) {
this.name = name;
this.price = price;
}
public void update_price(int up_price) {
this.price = up_price;
}
private float cal_discount(int discount) {
float discounted_price = (1 - discount / 100) * this.price;
return discounted_price;
}
}
现在,让我们创建家具类的 Class 对象。
Java 中的类 forName()
方法
Class 类提供了一个方法 forName()
来加载对象。
要使用此方法,我们必须知道要反映的类的名称。然后我们将类名作为参数传递给 forName()
方法。
看下面的代码:
Class class
= Class.forName("Furniture");
如果 Java 找不到该类,此方法将引发 ClassNotFoundException
。
Java 中的类 getClass()
方法
我们在要反映的类的对象上调用此方法。此方法返回对象的类。
看下面的代码:
Furniture furniture = new Furniture("Chair", 8565);
Class f = furniture.getClass();
我们还可以使用 .class
特性来获取类对象以进行 reflection。
// create a class object to relect on furniture
Class f = Furniture.class;
Java 中有用的 reflection 方法
类对象有以下三个方法,可以用来对类进行 reflection。
-
getName()
:此方法返回类的名称。 -
getModifiers()
:此方法返回一个表示类访问修饰符的整数。然后我们可以使用Modifier.toString()
方法将此整数转换为字符串。 -
getSuperclass()
:此方法返回方法的超类。
让我们看一个例子来理解这些方法。
import java.lang.reflect.Modifier;
public class SimpleTesting {
public static void main(String[] args) {
// create an object of furniture class
Furniture furniture = new Furniture("Chair", 8565);
// create a class object to relect on furniture
Class f = furniture.getClass();
// get the name of the class
String class_name = f.getName();
System.out.println("The class name is " + class_name);
// get the class modifier
int f_modifier = f.getModifiers();
String f_mod = Modifier.toString(f_modifier);
System.out.println("The modifier of the class is " + f_mod);
// get the superclass of the class
Class f_superclass = f.getSuperclass();
System.out.println("The Superclass of the class is " + f_superclass.getName());
}
}
输出:
The class name is Furniture
The modifier of the class is
The Superclass of the class is java.lang.Object
对方法进行 reflection
的有用方法
Java 提供了一个名为 Method 的类,它在 reflection 期间处理方法。
一个名为 getDeclaredMethods()
的方法返回一个包含类中定义的所有方法的数组。返回的方法属于类 Method。
Method 类包含几个用于检索有关类中方法的信息的方法。我们将使用方法类的以下方法:
-
Method.getName()
:此方法返回方法的名称。 -
Method.getModifiers()
:此方法返回一个整数,表示该方法的访问修饰符。 -
Method.getReturnType()
:此方法返回方法的返回类型。
让我们看一个例子来理解这些方法。
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class SimpleTesting {
public static void main(String[] args) {
// create an object of furniture class
Furniture furniture = new Furniture("Chair", 8565);
// create a class object to relect on furniture
Class f = furniture.getClass();
// using object f of Class to
// get all the declared methods of Furniture
Method[] f_methods = f.getDeclaredMethods();
for (Method f_method : f_methods) {
// get the name of the method
System.out.println("Method Name: " + f_method.getName());
// get the access modifier of methods
int f_modifier = f_method.getModifiers();
System.out.println("Modifier: " + Modifier.toString(f_modifier));
// get the return type of the methods
System.out.println("Return Types: " + f_method.getReturnType());
System.out.println(" ");
}
}
}
输出:
Method Name: update_price
Modifier: public
Return Types: void
Method Name: cal_discount
Modifier: private
Return Types: float
在上面的例子中,我们试图了解家具类中定义的方法。我们首先必须使用 getClass()
方法创建一个 Class 对象。
对字段进行 reflection
的有用方法
我们还可以使用 Field 类的方法检查和更改类的不同字段。有一种方法叫。
class.getField
(<field name>)
此方法接受一个参数:我们要访问的字段的名称,并返回所传递字段的 Field 对象。然后我们可以使用 Field 类对象来调用各种方法。
我们将使用 Field 类的以下方法。
-
Field.set()
:此方法设置字段的值。 -
Field.get()
:此方法返回存储在字段中的值。 -
Field.getModifier()
:此方法返回一个整数,表示字段的访问修饰符。
让我们看一个例子来理解这些方法。
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class SimpleTesting {
public static void main(String[] args) throws Exception {
// create object of the furniture class
Furniture furniture = new Furniture("Chair", 8565);
// create a class object to relect on furniture
Class f = furniture.getClass();
// using object f of Class to
// acces the name field of Furniture
Field f_name = f.getField("name");
// get the value of the field
String f_name_value = (String) f_name.get(furniture);
System.out.println("Field value before changing: " + f_name_value);
// changing the field value
f_name.set(furniture, "Table");
// get the value of the field
f_name_value = (String) f_name.get(furniture);
System.out.println("Field value after changing: " + f_name_value);
// get the access modifier
int f_name_mod = f_name.getModifiers();
// convert the access modifier to String form
String f_name_modifier = Modifier.toString(f_name_mod);
System.out.println("Modifier: " + f_name_modifier);
System.out.println(" ");
}
}
输出:
Field value before changing: Chair
Field value after changing: Table
Modifier: public
访问私有字段是类似的,除了我们必须使用方法 setAccessible()
并传递 true 作为其参数来修改私有字段的可访问性。
看下面的示例代码;我们正在尝试访问和修改家具类的私有字段价格。
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class SimpleTesting {
public static void main(String[] args) throws Exception {
// create object of the furniture class
Furniture furniture = new Furniture("Chair", 8565);
// create a class object to reflect on furniture
Class f = furniture.getClass();
// using object f of Class to
// access the price field of Furniture
Field f_price = f.getDeclaredField("price");
// modifying the accessibility
f_price.setAccessible(true);
// get the value of the field
int f_price_value = (Integer) f_price.get(furniture);
System.out.println("Field value before changing: " + f_price_value);
// changing the field value
f_price.set(furniture, 453);
// get the value of the field
f_price_value = (Integer) f_price.get(furniture);
System.out.println("Field value after changing: " + f_price_value);
// get the access modifier
int f_price_mod = f_price.getModifiers();
// convert the access modifier to String form
String f_price_modifier = Modifier.toString(f_price_mod);
System.out.println("Modifier: " + f_price_modifier);
System.out.println(" ");
}
}
输出:
Field value before changing: 8565
Field value after changing: 453
Modifier: private
结论
看完这篇文章,我们对 Java 中的 reflection 有了足够的了解。
我们还研究了 Java 中用于 reflection 的类和方法。我们学习了如何获取类的名称及其方法和字段。
使用 reflection API,我们可以快速获取类的信息。
相关文章
Java 中的 volatile 关键字
发布时间:2023/11/13 浏览次数:173 分类:Java
-
本文讨论了 Java 中的 volatile 关键字及其优缺点,并举例说明了如何使用。Java 是一种非常流行的编程语言,通过了解 Java,我们可以很容易地理解它为什么会在编程社区中获得这样的地位。
Java 中的 StringUtils
发布时间:2023/11/13 浏览次数:80 分类:Java
-
本文介绍 Java 中的 StringUtils 类是什么。本文介绍什么是 StringUtils 以及如何在 Java 中使用它来处理字符串。StringUtils 是一个用于处理 String 的类,它提供了比 Java String 类更多的实用方法。
Java 中的 flatMap
发布时间:2023/11/13 浏览次数:132 分类:Java
-
本文介绍 flatMap 以及如何在 Java 中使用它。本文介绍 flatMap 以及如何在 Java 中使用它。flatMap 是 Java 流中的一个操作/函数,用于在执行某些功能性任务后获取新流。在这里,我们将讨论 flatMap
在 Java 中将 Stream 元素转换为映射
发布时间:2023/11/13 浏览次数:77 分类:Java
-
我们将使用 Java 将流元素转换为映射。我们将向你展示如何使用 Collectors.toMap() 从 Java 字符串中提取映射。我们将讨论 Java Streams 的实际用途以及如何将流元素转换为映射元素。
Java 中的 findFirst 流方法
发布时间:2023/11/13 浏览次数:171 分类:Java
-
本教程介绍 Java 中的 findFirst 流方法。java.util.stream API 是在 Java 8 中引入的;它用于处理对象的集合。不同的源(例如数组或集合)可以创建流。
Java 中的 Stream 的 reduce 操作
发布时间:2023/11/13 浏览次数:147 分类:Java
-
本文介绍 Java 中 stream 的 reduce 操作。本文将讨论 reduce() 操作细节并讨论它的一些示例。在讨论 reduce() 操作之前。让我们首先讨论减少。
修复 Java NoClassDefFoundError 错误
发布时间:2023/11/13 浏览次数:199 分类:Java
-
本文介绍如何修复 Java 中的 NoClassDefFoundError。在 Java 语言中,错误是主要由于缺乏资源而发生的异常。此外,错误无法在编译时捕获并在运行时发生。
在 Java 中扩展 Comparable
发布时间:2023/10/19 浏览次数:97 分类:Java
-
本教程展示了如何在 Java 中清除 StringBuilder 本指南将了解在 Java 中扩展 Comparable 接口。它写成 Comparable
。它是一个由 Java 中的许多类实现的接口。
Java 中的 Predicate 是什么
发布时间:2023/10/19 浏览次数:109 分类:Java
-
本文介绍 Java 8 中的 Predicate 接口。本教程通过 Java 示例介绍 Predicate 接口。Predicate 是 Java 中的一个接口,用作 lambda 表达式或方法引用的目标赋值。