我们创建的所有类class是由JVM在执行过程中动态加载的。JVM在第一次读取到一种class类型时,将其加载进内存。每加载一种class,JVM就为其创建一个Class类型的实例。注意,这里的Class类型是一个名叫Class的class,它的定义大致是这样的:

    1. public final class Class {
    2. private Class() {
    3. }
    4. }

    比如说现在JVM要加载字符串类,那么首先会创建一个Class的实例:Class cls = new Class(),cls中存储有String类型所有相关信息,比如名称、完整类名等等。而这个cls又作为静态变量赋值给class String(具体机制不明),所以我们可以通过String.class或者通过变量引用Class cls = String.class来获取字符串类型的所有class信息,这个通过class实例获取class信息的过程称为反射。
    需要注意的是,上面的new Class()我们是无法使用的,因为它的构造方法是私有的(注意上面代码框),所以只有JVM可以创建Class实例。此外,上述过程对所有的类都适用,即使是我们自定义的类。同时,JVM对每一个类只会创建一个class实例(显然一个就够了)。

    除了通过类型的静态变量.class外,还有以下方式获取类相应的Class实例:

    • 如果已知一个类的实例:String s = "Hello"; Class cls = s.getClass();
    • 如果知道类的完整类名:Class cls = Class.forName("java.lang.String");

    典型示例:

    1. # 获取Class实例的相关信息
    2. public static void main(String[] args) {
    3. printClassInfo("".getClass());
    4. printClassInfo(Runnable.class);
    5. printClassInfo(java.time.Month.class);
    6. printClassInfo(String[].class);
    7. printClassInfo(int.class);
    8. }
    9. static void printClassInfo(Class cls) {
    10. System.out.println("Class name: " + cls.getName());
    11. System.out.println("Simple name: " + cls.getSimpleName());
    12. if (cls.getPackage() != null) {
    13. System.out.println("Package name: " + cls.getPackage().getName());
    14. }
    15. System.out.println("is interface: " + cls.isInterface());
    16. System.out.println("is enum: " + cls.isEnum());
    17. System.out.println("is array: " + cls.isArray());
    18. System.out.println("is primitive: " + cls.isPrimitive());
    19. }
    20. }
    1. # 获取字段
    2. public class Main {
    3. public static void main(String[] args) throws Exception {
    4. Class stdClass = Student.class;
    5. // 获取public字段"score":
    6. System.out.println(stdClass.getField("score"));
    7. // 获取继承的public字段"name":
    8. System.out.println(stdClass.getField("name"));
    9. // 获取private字段"grade":
    10. System.out.println(stdClass.getDeclaredField("grade"));
    11. }
    12. }
    13. class Student extends Person {
    14. public int score;
    15. private int grade;
    16. }
    17. class Person {
    18. public String name;
    19. }