反射2-获取class对象的三种方式

反射2-获取class对象的三种方式

一、反射

在Java中,Class对象是反射机制的起点,它代表了JVM中加载的类的元数据。获取Class对象就像拿到了"类的身份证",有了它才能进行反射操作(如动态创建对象、调用方法、修改字段等)。

通俗比喻:Class对象就像是每个Java类的"身份证",有了它,我们就能在运行时"认识"这个类,了解它的结构,甚至"操作"它的内部。

1. 反射的核心:Class对象

反射的起点是Class对象。每个类被JVM加载后,都会生成一个唯一的Class对象,该对象存储了类的完整结构信息,包括:

  • 类的名称、包名
  • 父类、实现的接口
  • 字段(Field)
  • 方法(Method)
  • 构造器(Constructor)

获取Class对象的三种方式

Class是一个Java中已经定义好的类,类名是Class,其中有一个静态方法forName(),参数是类名,就可以获得到相应类的字节码文件。

方式1:类名.class(类字面常量)

Class<?> classObject = ClassName.class;
原理解析
  • 编译时确定,JVM会加载该类并生成Class对象
  • 编译器会进行类型检查,确保类存在
  • 不会触发类的初始化(如果类有静态代码块,不会执行)

优点
  • ✅ 编译时检查,类型安全
  • ✅ 性能最好(不需要运行时解析)
  • ✅ 代码简洁
缺点
  • ❌ 无法动态获取类名(需要硬编码类名)
通俗理解

就像你直接在书架上找到某本书的书名,书名已经写在书架上,你不需要问别人,直接就能拿到。

方式2:对象.getClass()

Class<?> classObject = object.getClass();
原理解析
  • 通过已有的对象实例获取其Class对象
  • 该方法是Object类的final方法,所有对象都有
  • 会触发类的初始化(如果类有静态代码块,会执行)

优点
  • ✅ 简单直接,不需要知道类名
  • ✅ 适用于多态场景(获取运行时实际类型)
缺点
  • ❌ 必须先有对象实例,否则会抛出NullPointerException
  • ❌ 无法在没有对象的情况下获取Class对象
通俗理解

就像你手里已经有一本书,直接翻到书的版权页,就能看到这本书的"身份证"。

方式3:Class.forName()

Class<?> classObject = Class.forName("全限定类名");
原理解析
  • 通过类的全限定名(包名+类名)动态加载类
  • 会触发JVM的类加载机制
  • 会执行类的静态代码块(初始化类)

优点
  • ✅ 高度灵活,可以处理字符串形式的类名
  • ✅ 适合配置化、动态加载的场景
缺点
  • ❌ 需要处理ClassNotFoundException异常
  • ❌ 性能稍低(需要运行时解析类名)
  • ❌ 会触发类的初始化
通俗理解

就像你从图书馆的目录表上找到一本书的名称,然后去书架上找这本书,可能需要等待工作人员帮你找。

package com.lkbhua.MyreflectDemo1; public class demo1 { public static void main(String[] args) throws Exception { /* 获取class对象的三种方式: 1. Class.forName("全类名") 2. 对象.getClass() 3. 类名.class */ // 1、Class.forName("全类名") // 全类名: 包名 + 类名 // 第一种最为常用 Class clazz = Class.forName("com.lkbhua.MyreflectDemo1.Student"); // 2、打印 System.out.println(clazz); // 2、类名.class // 一般更多的是当作参数进行传递 多线程synchronized(clazz)中 Class clazz2 = Student.class; System.out.println(clazz2 == clazz); // 3、对象.getClass() // 局限性: 当我们已经有了这个类的对象时,才可以使用 Student s = new Student(); Class clazz3 = s.getClass(); System.out.println(clazz3 == clazz); } }

三种方式对比总结

方式语法是否需要实例是否触发类加载是否触发初始化灵活性性能安全性
类名.classClassName.class低(需硬编码)⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
对象.getClass()object.getClass()✔️✔️⭐⭐⭐⭐⭐⭐⭐⭐
Class.forName()Class.forName("全限定类名")✔️✔️高(可动态)⭐⭐⭐⭐

:⭐越多表示越好