Java反射通过Class.forName()加载类的全限定名并初始化,再用getDeclaredConstructor().newInstance()创建实例;内部类写法为“包名.外类$内类”,私有构造器需setAccessible(true),且需处理各类反射异常。

Java 反射机制可以通过类的全限定名(字符串)动态加载并实例化类,核心步骤是:先用 Class.forName() 加载类,再调用 newInstance()(旧方式)或更推荐的 getDeclaredConstructor().newInstance()(新方式)来创建对象。
使用 Class.forName() 加载类
这是反射的第一步,必须传入类的**全限定名**(包名 + 类名),例如 "java.util.ArrayList" 或 "com.example.MyService"。JVM 会查找、加载并初始化该类(触发静态代码块)。
- 如果类不存在或路径错误,抛出
ClassNotFoundException - 如果类存在但初始化失败(如静态块抛异常),抛出
ExceptionInInitializerError - 注意:内部类写法为
"com.example.Outer$Inner",不能用点号
获取构造器并实例化对象
不建议直接用已废弃的 Class.newInstance()(仅支持无参、public 构造器,且在 Java 9+ 中被标记为 deprecated)。应显式获取构造器再调用 newInstance():
- 无参构造器:
clazz.getDeclaredConstructor().newInstance() - 带参构造器:
clazz.getDeclaredConstructor(String.class, int.class).newInstance("hello", 42) - 若构造器是 private,需先调用
setAccessible(true)破除访问限制
完整示例代码
以下是一个安全、通用的封装方法:
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
public static <t> T newInstance(String className) throws Exception {
Class> clazz = Class.forName(className);
return (T) clazz.getDeclaredConstructor().newInstance();
}
// 使用示例
List<string> list = newInstance("java.util.ArrayList");
</string></t>
若目标类构造器有参数或为私有,需扩展逻辑,捕获 NoSuchMethodException、IllegalAccessException、InvocationTargetException 等异常并合理处理。
注意事项与常见问题
反射虽灵活,但有实际约束和风险:
- 类必须在 classpath / module path 中可见,否则
ClassNotFoundException - 泛型在运行时被擦除,反射创建的对象需手动强转,编译期不检查类型安全
- 性能开销较大,不宜高频调用;可考虑缓存
Class对象或Constructor实例 - 模块系统(Java 9+)下,若类所在模块未对反射调用方开放(
opens或exports),会抛出IllegalAccessError
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










