Java 反射

在 Java 中,反射允许我们在运行时检查和操作 接口构造函数方法 和字段。

Java 中有一个名为 Class 的类,它在运行时存储有关对象和类的所有信息。Class 的对象可用于执行反射。


Java 类反射

为了反射一个 Java 类,我们首先需要创建一个 Class 对象。

然后,我们可以使用该对象调用各种方法来获取有关类中存在的方法、字段和构造函数的信息。

创建 Class 对象的有三种方法

1. 使用 forName() 方法

class Dog {...}

// create object of Class
// to reflect the Dog class
Class a = Class.forName("Dog");

在这里,forName() 方法将其要反射的类的名称作为参数。

2. 使用 getClass() 方法

// create an object of Dog class
Dog d1 = new Dog();

// create an object of Class
// to reflect Dog
Class b = d1.getClass();

在这里,我们使用 Dog 类的对象来创建 Class 对象。

3. 使用 .class 扩展

// create an object of Class
// to reflect the Dog class
Class c = Dog.class;

现在我们知道了如何创建 Class 对象。我们可以使用此对象在运行时获取有关相应类的信息。


示例:Java 类反射

import java.lang.Class;
import java.lang.reflect.*;

class Animal {
}

// put this class in different Dog.java file
public class Dog extends Animal {
  public void display() {
    System.out.println("I am a dog.");
  }
}

// put this in Main.java file
class Main {
  public static void main(String[] args) {
    try {
      // create an object of Dog
      Dog d1 = new Dog();

      // create an object of Class
      // using getClass()
      Class obj = d1.getClass();

      // get name of the class
      String name = obj.getName();
      System.out.println("Name: " + name);

      // get the access modifier of the class
      int modifier = obj.getModifiers();

      // convert the access modifier to string
      String mod = Modifier.toString(modifier);
      System.out.println("Modifier: " + mod);

      // get the superclass of Dog
      Class superClass = obj.getSuperclass();
      System.out.println("Superclass: " + superClass.getName());
    }

    catch (Exception e) {
      e.printStackTrace();
    }
  }
}

输出

Name: Dog
Modifier: public
Superclass: Animal

在上面的示例中,我们创建了一个超类 Animal 和一个子类 Dog。在这里,我们尝试检查 Dog 类。

请注意以下语句:

Class obj = d1.getClass();

在这里,我们使用 getClass() 方法创建了一个 Class 的对象 obj。使用该对象,我们调用 Class 的各种方法。

  • obj.getName() - 返回类的名称
  • obj.getModifiers() - 返回类的访问修饰符
  • obj.getSuperclass() - 返回类的超类

要了解更多关于 Class 的信息,请访问 Java Class (官方 Java 文档)

注意:我们使用 Modifier 类将整数访问修饰符转换为 字符串


反射字段、方法和构造函数

java.lang.reflect 包提供了可用于操作类成员的类。例如,

  • Method 类 - 提供有关类中方法的信息
  • Field 类 - 提供有关类中字段的信息
  • Constructor 类 - 提供有关类中构造函数的信息

1. Java 方法反射

Method 类提供了各种方法,可用于获取有关类中存在的方法的信息。例如,

import java.lang.Class;
import java.lang.reflect.*;

class Dog {

  // methods of the class
  public void display() {
    System.out.println("I am a dog.");
  }

  private void makeSound() {
    System.out.println("Bark Bark");
  }
}

class Main {
  public static void main(String[] args) {
    try {

      // create an object of Dog
      Dog d1 = new Dog();

      // create an object of Class
      // using getClass()
      Class obj = d1.getClass();

      // using object of Class to
      // get all the declared methods of Dog
      Method[] methods = obj.getDeclaredMethods();

      // create an object of the Method class
      for (Method m : methods) {

        // get names of methods
        System.out.println("Method Name: " + m.getName());

        // get the access modifier of methods
        int modifier = m.getModifiers();
        System.out.println("Modifier: " + Modifier.toString(modifier));

        // get the return types of method
        System.out.println("Return Types: " + m.getReturnType());
        System.out.println(" ");
      }
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }
}

输出

Method Name: display
Modifier: public
Return Types: void
 
Method Name: makeSound
Modifier: private
Return Types: void

在上面的示例中,我们试图获取 Dog 类中存在的方法的信息。如前所述,我们首先使用 getClass() 方法创建了 Class 的对象 obj

注意表达式:

Method[] methods = obj.getDeclaredMethod();

在这里,getDeclaredMethod() 返回类中存在的所有方法。

此外,我们还创建了 Method 类的对象 m。这里,

  • m.getName() - 返回方法的名称
  • m.getModifiers() - 以整数形式返回方法的访问修饰符
  • m.getReturnType() - 返回方法的返回类型

Method 类还提供了各种其他方法,可用于在运行时检查方法。要了解更多,请访问 Java Method 类 (官方 Java 文档)


2. Java 字段反射

与方法类似,我们还可以使用 Field 类的方法来检查和修改类的不同字段。例如,

import java.lang.Class;
import java.lang.reflect.*;

class Dog {
  public String type;
}

class Main {
  public static void main(String[] args) {
    try {
      // create an object of Dog
      Dog d1 = new Dog();

      // create an object of Class
      // using getClass()
      Class obj = d1.getClass();

      // access and set the type field
      Field field1 = obj.getField("type");
      field1.set(d1, "labrador");

      // get the value of the field type
      String typeValue = (String) field1.get(d1);
      System.out.println("Value: " + typeValue);

      // get the access modifier of the field type
      int mod = field1.getModifiers();

      // convert the modifier to String form
      String modifier1 = Modifier.toString(mod);
      System.out.println("Modifier: " + modifier1);
      System.out.println(" ");
    }
    
    catch (Exception e) {
      e.printStackTrace();
    }
  }
}

输出

Value: labrador
Modifier: public

在上面的示例中,我们创建了一个名为 Dog 的类。它包含一个名为 type 的公共字段。注意语句:

Field field1 = obj.getField("type");

在这里,我们访问 Dog 类的公共字段,并将其分配给 Field 类的对象 field1

然后,我们使用 Field 类的各种方法

  • field1.set() - 设置字段的值
  • field1.get() - 返回字段的值
  • field1.getModifiers() - 以整数形式返回字段的值

同样,我们也可以访问和修改私有字段。但是,私有字段的反射与公共字段略有不同。例如,

import java.lang.Class;
import java.lang.reflect.*;

class Dog {
  private String color;
}

class Main {
  public static void main(String[] args) {
    try {
      // create an object of Dog
      Dog d1 = new Dog();

      // create an object of Class
      // using getClass()
      Class obj = d1.getClass();

      // access the private field color
      Field field1 = obj.getDeclaredField("color");

      // allow modification of the private field
      field1.setAccessible(true);

      // set the value of color
      field1.set(d1, "brown");

      // get the value of field color
      String colorValue = (String) field1.get(d1);
      System.out.println("Value: " + colorValue);

      // get the access modifier of color
      int mod2 = field1.getModifiers();

      // convert the access modifier to string
      String modifier2 = Modifier.toString(mod2);
      System.out.println("Modifier: " + modifier2);
    }
    
    catch (Exception e) {
      e.printStackTrace();
    }
  }
}

输出

Value: brown
Modifier: private

在上面的示例中,我们创建了一个名为 Dog 的类。该类包含一个名为 color 的私有字段。注意语句。

Field field1 = obj.getDeclaredField("color");

field1.setAccessible(true);

在这里,我们正在访问 color 并将其分配给 Field 类的对象 field1。然后,我们使用 field1 来修改 color 的可访问性,并允许我们对其进行更改。

然后,我们使用 field1 对私有字段 color 执行各种操作。

要了解有关 Field 不同方法的更多信息,请访问 Java Field 类 (官方 Java 文档)


3. Java 构造函数反射

我们还可以使用 Constructor 类提供的各种方法来检查类的不同构造函数。例如,

import java.lang.Class;
import java.lang.reflect.*;

class Dog {

  // public constructor without parameter
  public Dog() {

  }

  // private constructor with a single parameter
  private Dog(int age) {

  }

}

class Main {
  public static void main(String[] args) {
    try {
      // create an object of Dog
      Dog d1 = new Dog();

      // create an object of Class
      // using getClass()
      Class obj = d1.getClass();

      // get all constructors of Dog
      Constructor[] constructors = obj.getDeclaredConstructors();

      for (Constructor c : constructors) {

        // get the name of constructors
        System.out.println("Constructor Name: " + c.getName());

        // get the access modifier of constructors
        // convert it into string form
        int modifier = c.getModifiers();
        String mod = Modifier.toString(modifier);
        System.out.println("Modifier: " + mod);

        // get the number of parameters in constructors
        System.out.println("Parameters: " + c.getParameterCount());
        System.out.println("");
      }
    }
    
    catch (Exception e) {
      e.printStackTrace();
    }
  }
}

输出

Constructor Name: Dog
Modifier: public     
Parameters: 0        

Constructor Name: Dog
Modifier: private    
Parameters: 1

在上面的示例中,我们创建了一个名为 Dog 的类。该类包含两个构造函数。

我们使用反射来查找有关类构造函数的信息。注意语句:

Constructor[] constructors = obj.getDeclaredConstructor();

在这里,我们访问 Dog 中存在的所有构造函数,并将它们分配给 Constructor 类型的数组 constructors

然后,我们使用对象 c 来获取有关构造函数的不同信息。

  • c.getName() - 返回构造函数的名称
  • c.getModifiers() - 以整数形式返回构造函数的访问修饰符
  • c.getParameterCount() - 返回每个构造函数中存在的参数数量

要了解有关 Constructor 类更多方法的更多信息,请访问 Constructor 类

你觉得这篇文章有帮助吗?

我们的高级学习平台,凭借十多年的经验和数千条反馈创建。

以前所未有的方式学习和提高您的编程技能。

试用 Programiz PRO
  • 交互式课程
  • 证书
  • AI 帮助
  • 2000+ 挑战