Java 中使用反射的步骤及相关API

188 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第31天,点击查看活动详情

这篇文章我们介绍一些Java 中使用反射的步骤。

如何使用反射获取一个对象

我们来看一下使用反射获取一个对象的步骤:

  1. 首先我们要获取类的Class 对象实例(注意Class 与定义类的时候的class 关键字的区别)
Class clz = Class.forName("com.xxx.xxx.Chocolate");
  1. 根据定义的Class 的对象实例clz 来获取Constructor 对象
Constructor chocolate = clz.getConstructor();
  1. 根据Constructor 类的实例对象constructor 的newInstance 方法获取反射类的对象
Object obj = constructor.newInstance();
  1. 为了调用反射类对象的方法,首先要获得方法的Method 对象
Method setPriceMethod = clz.getMethod("setPrice", String.class);
  1. 得到Method 类的实例对象的setPriceMethod 实例后,利用 invoke 方法进行调用。invoke 方法中传入反射类对象实例及方法参数
setPriceMethod.invoke(obj, "12.35");

以上五个步骤就是最基本的反射使用的步骤。接下来我们了介绍一些反射常用的API。

对于反射常用的API,大致可以分为以下几种:

  1. 根据传入的实际需要实例化的类的字符串,获得反射的Class 对象(Class clz)
  2. 获得实际需要使用的类对象(Object obj)
  3. 获得实际待使用的类属性方法、构造器(Method method / Constructor constructor)

我们接下来分别看一下这些常用的API。

获取反射中的Class对象

如果使用Java 开发相关业务的时候,首先就是需要获取一个类,然后调用其方法来完成我们的相关业务流程。在使用反射的时候,我们第一步就是要获取对应类的Class 对象。获取Class 对象一共有三种方法:

  1. 使用Class.forName 这是个静态方法,只有在当我们知道某个类的的全路径名的时候,我们才可以使用这个方法来获取Class 类对象。如:
Class clz = Class.forName("com.xxx.xxx.Chocolate");
  1. 使用.class 方法。 在写代码的时候,未经编译就知道的类的时候可以使用这个方法。如:
Class clz = Chocolate.class;
  1. 直接使用类对象的getClass() 方法
Chocolate chocolate = new Chocolate();
Class clz = chocolate.getClass();

获取实际需要使用的类对象

使用反射创建待使用的类的对象有两种方法,我们来分别介绍一下。

  1. 通过使用Class 对象的newInstance() 方法来创建
Class clz = Chocolate.class;
Chocolate chocolate = (Chocolate)clz.newInstance();
  1. 使用Constructor 实例对象的newInstance() 方法
Class clz = Chocolate.class;
Constructor constructor = clz.getConstructor();
Chocolate chocolate = (Chocolate)constructor.newInstance();

对于以上两种方法的区别就是在使用Constructor 对象去创建待使用的类对象的时候,可以选择某个特定的构造方法;而使用Class 对象的时候,就只能使用默认的无参数构造方法。

我们举例看一下如何使用一个有参数的构造方法进行类对象的初始化。

Class clz = Chocolate.class;
// 括号里的两个参数就是有参构造方法中的参数类型
Constructor constructor = clz.getConstructor(String.class, String.class);
Chocolate chocolate = (Chocolate)constructor.newInstance("12.35", "black");

通过反射获得目标类的属性、方法和构造器

我们通过声明的Class 对象(clz)的getFields() 方法可以获取Class 类的属性,但是这个方法时无法获得类的私有属性的。举例代码如下:

Class clz = Chocolate.class;
Field[] fields = clz.getFields();
for (Field field : fields) {
    System.out.println(field.getName());
}

然后JDK 提供了一种方法:getDeclaredFields(),这个方法则可以获取包括声明的属性,包括私有属性。

Class clz = Chocolate.class;
Field[] fields = clz.getDeclaredFields();
for (Field field : fields) {
    System.out.println(field.getName());
}

获取方法、构造器的流程与获取属性的流程一致,这里就不再赘述了。

总结

这篇文章介绍的是Java 中反射的使用步骤,同时介绍了JDK 中的反射相关的API,比较容易理解,读者可以在实际工作中尝试使用。