java反射机制支持运行时动态获取类结构并调用成员,通过class对象(类名.class、对象.getclass()、class.forname)获取元数据,再利用method/field/constructor操作私有或公有成员,需注意访问权限、类初始化及异常处理。

Java反射机制允许程序在运行时动态获取类的结构信息(如构造器、字段、方法)并调用它们,无需编译期确定类型。关键在于通过Class对象访问元数据,并借助Method、Field、Constructor等类完成操作。
获取Class对象的三种常用方式
反射的第一步是拿到目标类的Class对象:
-
类名.class:适用于已知类名且编译期可访问的情况,例如
String.class -
对象.getClass():适用于已有实例,如
new ArrayList().getClass() -
Class.forName("全限定类名"):支持字符串形式的类名,常用于配置驱动或插件加载,例如
Class.forName("java.util.Date")
注意:forName()会触发类的初始化(执行静态代码块),而.class和getClass()不会。
获取并遍历类的成员信息
通过Class对象可查询各类成员,需注意访问权限控制:
- getDeclaredMethods() 返回本类所有方法(含私有),但不包括继承的;getMethods() 只返回public方法(含继承的)
- getDeclaredFields() 获取本类全部字段(含私有),getFields() 仅返回public字段(含继承的)
- getDeclaredConstructors() 获取本类所有构造器,getConstructors() 仅返回public构造器
每个返回的数组元素都支持获取名称、参数类型、返回类型、注解等信息,例如method.getName()或field.getType()。
动态调用方法与访问字段
获取到Method或Field对象后,需处理访问权限并执行:
- 对私有成员调用
setAccessible(true)绕过访问检查(JDK 12+默认更严格,可能需配合启动参数) - 调用
method.invoke(对象实例, 参数...),若为静态方法,第一个参数传null - 读写字段用
field.get(对象实例)和field.set(对象实例, 值),静态字段同样传null作为实例
示例:调用私有方法private String getValue() { return "secret"; },需先method.setAccessible(true)再method.invoke(obj)。
创建对象与处理异常
反射创建实例比new更灵活,但也更易出错:
- 使用
clazz.getDeclaredConstructor(参数类型...).newInstance(参数...)可调用任意构造器(含私有) - 常见异常需捕获:
NoClassDefFoundError(类未加载)、ClassNotFoundException(forName失败)、IllegalAccessException(访问受限)、InvocationTargetException(被调方法抛出异常,原异常在.getCause()中)
建议优先使用try-catch包裹具体反射操作,而非笼统捕获Exception,便于定位问题根源。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











