getClass() 不触发类加载,仅返回已加载类的 Class 对象;类加载由 ClassLoader 在首次主动使用时完成,getClass() 是反射操作的前提而非加载机制。

getClass() 本身不参与类加载,它返回已有实例的 Class 对象,而类加载发生在实例创建之前。很多人误以为 getClass() 能触发或控制类加载,其实它只是反射的“起点”——拿到 Class 对象后,才能进一步用反射做动态操作。真正负责类加载的是 ClassLoader,getClass() 和它没有调用关系。
getClass() 的作用是获取运行时类型信息
每个 Java 对象都有 getClass() 方法(继承自 Object),调用它会返回该对象实际所属类的 Class 实例。这个 Class 对象是 JVM 在类加载阶段已生成并缓存好的元数据载体。
- 它不加载新类,只访问已加载类的信息
- 即使类从未被显式引用过,只要对象存在,说明该类早已被加载(否则 new 都无法成功)
- 返回的 Class 对象可用来获取字段、方法、构造器等,是反射操作的前提
类加载实际由 ClassLoader 完成,与 getClass() 无关
类加载过程(加载 → 链接 → 初始化)由 ClassLoader(如 AppClassLoader、BootstrapClassLoader)驱动,通常在以下时机触发:
- 首次主动使用类:new 实例、调用静态方法/字段、反射中的
Class.forName("xxx") -
getClass()出现在这些动作之后,属于“事后查询” - 例如:
String s = "hello"; s.getClass();—— String 类早在 main 启动时就被 BootstrapClassLoader 加载了
如何配合反射做动态行为?关键是用 Class 对象继续操作
拿到 getClass() 返回的 Class 后,可结合反射实现运行时动态调用,但注意:这依赖类已加载,不是靠 getClass() 加载的。
立即学习“Java免费学习笔记(深入)”;
- 获取类名:
obj.getClass().getName() - 获取公共方法并调用:
obj.getClass().getMethod("toString").invoke(obj) - 获取私有字段(需 setAccessible):
obj.getClass().getDeclaredField("value").get(obj) - 若需加载一个尚未使用的类,应改用
Class.forName("com.example.Foo")或ClassLoader.loadClass("com.example.Foo")
常见误区提醒
避免混淆几个关键点:
-
getClass()返回的是具体运行时类(可能为子类),而Class.forName()指定的是编译期类名 - 子类对象调用
getClass()返回子类 Class,不是父类;这对多态场景下的反射调用很关键 - 如果对象为 null,调用
getClass()会抛出 NullPointerException —— 它不能用于空值判断或延迟加载


















