迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 > Java >

Java 中的 reflection 是什么

作者:迹忆客 最近更新:2023/11/13 浏览次数:

本文介绍 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,我们可以快速获取类的信息。

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

Do you understand JavaScript closures?

发布时间:2025/02/21 浏览次数:108 分类:JavaScript

The function of a closure can be inferred from its name, suggesting that it is related to the concept of scope. A closure itself is a core concept in JavaScript, and being a core concept, it is naturally also a difficult one.

Do you know about the hidden traps in variables in JavaScript?

发布时间:2025/02/21 浏览次数:178 分类:JavaScript

Whether you're just starting to learn JavaScript or have been using it for a long time, I believe you'll encounter some traps related to JavaScript variable scope. The goal is to identify these traps before you fall into them, in order to av

How much do you know about the Prototype Chain?

发布时间:2025/02/21 浏览次数:150 分类:JavaScript

The prototype chain can be considered one of the core features of JavaScript, and certainly one of its more challenging aspects. If you've learned other object-oriented programming languages, you may find it somewhat confusing when you start

在 Pandas 的列中展平层次索引

发布时间:2024/04/24 浏览次数:1782 分类:Python

在这篇文章中,我们将使用不同的函数来使用 Pandas DataFrame 列来展平层次索引。我们将使用的方法是重置索引和 as_index() 函数。

Pandas 中的 Groupby 索引列

发布时间:2024/04/23 浏览次数:89 分类:Python

本教程将介绍如何使用 Python Pandas Groupby 对数据进行分类,然后将函数应用于类别。通过示例使用 groupby() 函数按 Pandas 中的多个索引列进行分组。

Pandas 中的散点矩阵

发布时间:2024/04/23 浏览次数:125 分类:Python

本教程演示了如何使用 scatter_matrix 函数在 Pandas 中创建散点图。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便