Java 反射机制

2018-04-07  本文已影响0人  EdwardLiuAurora

Java 反射机制

概述

通俗易懂的来说,反射是可以理解为 Java 运行时的一本说明书。这本说明书里面,记录着被加载到 Java 虚拟机中 Class 对象的名字、域、方法信息,无论这些信息是私有的还是公有的。我们可以通过这本说明书,来在运行时了解一个类的信息,然后根据这些信息,再进行动态的调用。

作用

作用机制

Java虚拟机加载完类之后,会在堆内存中产生一个 ==Class== 类型的对象(每个类只有一个Class对象),这个对象包含了完整的类的结构信息。这也是 Java 反射得名的原因——这个Class包含了完整的类的结构信息,就像一面镜子。

p.s. Java 的八种原始类型以及关键字 void 也会被视为 Class 对象。

获取 Class 对象

假设有一个类 Car,一个类型为 Car 的对象 car,我们有以下三种方法获取 Class 对象:

怎么利用 Class 类

==java.lang.reflect== 包中有三个类 Field 、 Method 和 Constructor,分别用于描述类的域、方法和构造器。

我们可以从==Class==类中获取包括构造函数、方法、属性、修饰符等信息,下面是常用的方法列表:

方法的作用 方法的签名 方法的包
返回一个类的新实例 Object newInstance() java.lang.Class 1.0
构造一个这个构造器所属类的新实例 Object newInstance(Object[] args) java.lang.reflect.Constructor 1.1
返回这个类和其超类的公有域 Field[] getFields() java.lang.Class 1.0
返回这个类的全部域 Field[] getDeclaredFields() java.lang.Class 1.0
返回这个类和其超类的公有方法 Method[] getMethods() java.lang.Class 1.0
返回这个类的全部方法 Method[] getDeclaredMethods() java.lang.Class 1.0
返回这个类的公有构造器 Constructor[] getConstructors() java.lang.Class 1.0
返回这个类的所有构造器 Constructor[] getDeclaredConstructors() java.lang.Class 1.0
调用一个对象所描述的方法 Object invoke(Object implicitParameter, Object[] explicitParameters) java.lang.reflect.Method 1.1
... ... ...

更多方法请查阅 java.lang.reflect 文档

创建对象

通过反射来生成对象的方式有两种:

调用方法

当获取到某个类对应的 Class 对象之后, 就可以通过该 Class 对象的 ==getMethod== 来获取一个 Method 数组或 Method 对象。每个 Method 对象对应一个方法,在获得 Method 对象之后,就可以通过调用 ==invoke== 方法来调用该 Method 对象对应的方法.

访问成员变量

通过 ==Class== 对象的的 ==getField()== 方法可以获取该类所包含的全部或指定的成员变量 Field ,Field 提供了如下两组方法来读取和设置成员变量值.

具体应用场景

利用反射实现工厂模式,从此,我们将对象的实例化操作,分离到了工厂类中去实现。我们可以利用反射实现的工厂模式,对编程进行解耦操作。如下,将 Car 对象的实例化操作,交给了 CarFactory 实现,我们只需要将所需要实例化的对象的类名,以 String 形式传入工厂即可:

package Reflect;

interface Car {
    public void accelerate();
    public void brake();
}

class Cadillac implements Car {
    public void accelerate() {
        System.out.println("凯迪拉克加速");
    }
    public void brake() {
        System.out.println("凯迪拉克刹车");
    }
}

class Buick implements Car {
    public void accelerate() {
        System.out.println("别克加速");
    }
    public void brake() {
        System.out.println("别克刹车");
    }
}

class CarFactory {
    public static Car getInstance(String CarClassName) {
        Car car = null;
        try {
            car = (Car) Class.forName(CarClassName).newInstance();
        }
        catch(Exception e) {
            e.printStackTrace();
        }
        return car;
    }
}

class Test {
    public static void main(String[] args) {
        Car car = CarFactory.getInstance("Reflect.Cadillac");
        if(car != null){
            car.accelerate();
            car.brake();
        }
        car = CarFactory.getInstance("Reflect.Buick");
        if(car != null){
            car.accelerate();
            car.brake();
        }
    }
}

刘丰璨 写于 2018.04.06 21:00 Github: https://github.com/EdwardLiu-Aurora

参考目录:

  1. 《Java 核心技术 卷 I 》
  2. 《Java 反射》
  3. 《利用反射机制实现工厂模式》
上一篇 下一篇

猜你喜欢

热点阅读