简介
获取Class
误区
解释一下 “类” 和 “Class对象” 的区别,以及为什么每个类都有关联的 Class 对象:
🧩 核心概念:类 vs Class对象
想象你有一本《汽车使用说明书》:
- 类 = 这本说明书本身(纸上的文字和图纸)
- Class对象 = 这本说明书的电子档案(包含所有信息的数字副本)
🌰 实际代码示例
// 1. 定义一个普通类
public class Car {String color;public void drive() {System.out.println("Driving...");}
}// 2. 获取该类的Class对象
public class Main {public static void main(String[] args) {// 方式1:通过类名获取Class<?> carClass1 = Car.class; // 这就是Car类的"档案袋"// 方式2:通过对象获取Car myCar = new Car();Class<?> carClass2 = myCar.getClass(); // 同一个档案袋System.out.println(carClass1 == carClass2); // 输出 true(同一个对象)// 3. 查看档案袋里的信息System.out.println("类名: " + carClass1.getName()); // 输出: CarSystem.out.println("方法数量: " + carClass1.getMethods().length); // 输出: 所有方法的数量}
}
📦 Class对象到底是什么?
-
它是JVM自动创建的
当Java程序启动时,JVM会为每个加载的类(包括系统类和你自定义的类)自动创建一个特殊的Class
类型对象。 -
它包含的信息
包含的内容 示例 类名 "Car"
字段信息 color
字段的类型、名称方法信息 drive()
方法的参数、返回值父类信息 继承自哪个父类 注解信息 类上的注解标记 类修饰符 public
,abstract
等 -
它存放在哪里?
- 存放在JVM的方法区(Method Area)中
- 每个类只有一个对应的Class对象(单例)
🔍 为什么需要Class对象?
-
反射机制的基础
让程序在运行时能"查看"类的结构:// 动态获取类信息(无需知道具体类) Class<?> unknownClass = Class.forName("com.example.UnknownClass"); Method[] methods = unknownClass.getMethods(); // 获取所有方法
-
类型检查
if(obj.getClass() == Car.class) {System.out.println("这是一个Car对象"); }
-
框架设计的核心
Spring、Hibernate等框架都依赖Class对象来:- 动态创建对象
- 自动注入依赖
- 处理注解配置
🆚 关键区别总结
普通类 (如Car) | Class对象 (如Car.class) | |
---|---|---|
本质 | 你写的代码(模板) | JVM创建的元数据对象 |
创建 | 由开发者定义 | 由JVM自动创建 |
内容 | 字段/方法的实现 | 类的描述信息(元数据) |
用途 | 创建对象 (new Car() ) | 反射操作 (getMethods() ) |
位置 | 源代码文件 (.java) | JVM内存中 |
💡 生活化比喻
想象一家汽车工厂:
- 类 = 汽车设计图纸(定义如何造车)
- Class对象 = 工厂的物料清单(记录需要多少轮胎、发动机型号等)
- 对象 = 实际造出来的汽车(根据图纸生产的实体)
每个设计图纸(类)在工厂(JVM)中都有对应的物料清单(Class对象),这样工厂才能知道如何正确生产汽车(对象)。
这种机制是Java反射能力的核心基础,让程序能在运行时动态了解和处理类信息。
反射获取类中的成分并操作
成员方法
构造器
成员变量
作用
破坏封装性
被private的依旧可以通过暴力反射操作。
破坏泛型的约束性
原本只可以加String,用反射之后就可以add其他类型的变量。