反射
2025/12/3大约 2 分钟
什么是反射?
Java反射机制是运行时动态获取类信息、操作对象成员的能力:
- 对任意类,能获取其所有属性、方法、构造器等结构信息。
- 对任意对象,能调用其任意方法(包括私有方法)、访问/修改其任意字段(包括私有字段)。
反射的核心特性
- 运行时类信息访问:无需编译时知道类名,即可在运行时获取类的包名、父类、接口、成员等信息。
- 动态对象创建:通过
Class.newInstance()或Constructor.newInstance(),运行时动态创建对象(无需new关键字)。 - 动态方法调用:通过
Method.invoke(),运行时调用对象的方法(包括私有方法)。 - 字段访问与修改:通过
Field.get()/Field.set(),运行时访问/修改对象的字段(包括私有字段)。
反射在你平时写代码或者框架中的应用场景有哪些?
反射在框架开发和动态编程中应用广泛,常见场景如下:
1. 加载数据库驱动(JDBC)
JDBC通过反射动态加载不同数据库的驱动类,无需硬编码驱动实现,适配多数据库。
// 传统硬编码(不推荐)
// 硬编码写法:new Driver() 触发自动注册 + 手动调用 registerDriver → 重复注册。
// 反射写法:仅触发类加载时的自动注册 → 无重复。
// DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver());
// 反射加载(灵活适配mysql/oracle)
Class.forName("com.mysql.cj.jdbc.Driver"); // 加载mysql驱动
// Class.forName("oracle.jdbc.driver.OracleDriver"); // 加载oracle驱动2. 框架的IOC容器(如Spring)
Spring 的 IOC 底层通过注解扫描 + 反射来自动完成的。
具体流程:
扫描注解
Spring 根据@ComponentScan扫描项目中的类,找到带@Component、@Service、@Controller、@Bean等注解的类。生成 BeanDefinition
Spring 解析这些类的元数据(类名、作用域、依赖等),统一存到 BeanDefinition 中。反射创建对象
Spring 根据 BeanDefinition 使用反射创建实例:
clazz.getDeclaredConstructor().newInstance();反射注入依赖
对于@Autowired、@Resource等,Spring 用反射给属性或构造器注入依赖。放入 IOC 容器
所有实例都放进容器(实际上是一个 Map)。
简洁总结:
Spring IOC 通过包扫描找到需要托管的类,生成元数据,然后用反射创建对象、注入依赖,并存放在 IOC 容器里。无需写类名,因为 Spring 自己能扫描并识别。