Java反射(一):Class类

152 阅读2分钟

Class类

Java中的引用数据类型

Java中的数据类型分为两种:基本数据类型和引用数据类型。 引用数据类型指向类class的实例(即对象)

引用类型 (1).png

对类class进行抽象

对于每个类class,我们可以抽象出一个类去描述,即Class类(名为Class的类class)。这样,String类Number类System类等等都可以都为Class类的实例(单例)。

//简易Class类(具体请看jdk源码)
public final class Class {
    private Class() {}
    //......
}

类class是由JVM在执行过程中动态加载的。 JVM在第一次读取到一种类class时,将其加载进内存。每加载一种类class,JVM就为其创建一个Class类的实例,并关联起来。

查看jdk源码,可以发现Class类的构造方法为private,即只有JVM能创建Class类实例,我们自己的Java程序是无法创建Class类实例。

由于JVM为每个加载的类class创建了对应的Class类实例,并在实例中保存了该类class的所有信息,包括类名包名父类、实现的接口、所有方法字段等,因此,如果获取了某个Class类实例,我们就可以通过这个Class类实例获取到该实例对应的类class的所有信息。

这种通过Class类实例获取类class信息的方法称为反射。

获取Class类实例

public class Main {
    public static void main(String[] args) throws Exception {
        // 方法一:通过类class的静态变量class获取
        Class cls1 = Student.class;
        // 方法二:通过类class的实例变量提供的getClass()方法获取
        Class cls2 = new Student().getClass();
        // 方法三:通过Class类的静态方法forName()获取,参数为类路径
        Class cls3 = Class.forName("stu.sujie.test.Student");
        // 方法四:通过类加载器的方法loadClass传入,参数为类路径
        ClassLoader classLoader = ClassLoader.getSystemClassLoader();
        Class cls4 = classLoader.loadClass("stu.sujie.test.Student");
    }
}

因为Class类实例在JVM中是单例的,所以,上述方法获取的Class类实例是同一个实例。

注:通过类加载器获取 Class 对象不会进行初始化,意味着不进行包括初始化等一些列步骤,static静态块和静态对象不会得到执行

总结

  • JVM为每个加载的类class创建了对应的Class类实例来保存class的所有信息

  • 获取一个类class对应的Class类实例后,就可以获取该类class的所有信息

  • 通过Class实例获取类class信息的方法称为反射

  • JVM总是动态加载类class