反射的原理?反射创建类实例的三种方式是什么?¶
一、反射是什么¶
Java 反射允许程序在运行时获取类信息、调用方法、访问字段,即使编译期不知道类型。
核心类:
Class:类的字节码对象。Method:方法。Field:字段。Constructor:构造器。
二、原理¶
类加载后,JVM 在方法区保存类的元数据(方法表、字段表)。反射通过这些元数据直接操作,绕过编译期的类型检查。
Class<?> cls = Class.forName("com.example.User");
Method m = cls.getMethod("sayHello");
Object obj = cls.newInstance();
m.invoke(obj);
三、创建实例的三种方式¶
1. Class.newInstance()(已废弃)¶
JDK9 废弃,因为只能调无参构造,异常不友好。
2. Constructor.newInstance()(推荐)¶
Constructor<?> ctor = Class.forName("com.example.User")
.getConstructor(String.class, int.class);
Object obj = ctor.newInstance("张三", 18);
可以调任意参数的构造器。
3. Class.forName + newInstance¶
本质和方式 1 一样。
4. (补充)clazz.getDeclaredConstructor().newInstance()¶
JDK9+ 推荐:
四、反射的优缺点¶
优点¶
- 灵活,框架(Spring、JDBC)必备。
- 运行时才知道类名。
缺点¶
- 性能比直接调用慢(要做安全检查、方法表查找)。
- 破坏封装(可以访问 private)。
- 编译期类型检查失效。
五、Spring 怎么优化反射¶
- 缓存 Method/Field。
setAccessible(true)关闭安全检查。- JIT 会内联反射调用。
高频追问
- 反射破坏单例:可以 new 私有构造器。
- 反射和泛型:编译期擦除,运行时拿不到泛型类型。