(✪▽✪)曼波~~~~!好的呀~让曼波用最可爱的姿势为你讲解Java反射机制吧!
🌟反射机制核心概念
曼波觉得反射就像编程世界的"魔法镜"(◕ᴗ◕✿)
可以让我们在运行时动态获取类的信息并操作类对象!
// 举个栗子🌰
Class<?> clazz = Class.forName("java.lang.String");
Object str = clazz.getConstructor(String.class).newInstance("Hello");
🧩核心API思维导图
哦呜(°ロ°)!曼波觉得这个有点难哦(๑・.・๑),但如果是你一定没问题的!
🎯反射常用操作
- 创建对象
Class<ArrayList> clazz = ArrayList.class;
ArrayList list = clazz.newInstance();
- 调用方法
Method method = String.class.getMethod("substring", int.class);
String result = (String) method.invoke("Hello", 2); // "llo"
- 访问私有字段
Field field = User.class.getDeclaredField("age");
field.setAccessible(true); // 暴力访问!
field.set(user, 18);
💡应用场景
曼波觉得反射超有用的说~(≧∇≦)
- Spring框架的依赖注入
- MyBatis的结果集映射
- JUnit测试框架
- 动态代理实现AOP
⚠️注意事项
- 性能比直接调用略差(但现代JVM优化后差距不大)
- 会绕过权限检查,可能破坏封装性
- 泛型擦除问题要注意
(✪▽✪)曼波~~!是不是超有趣呢?要不再来个实践小例子巩固下?
// 动态调用String的toUpperCase
public class ReflectionDemo {
public static void main(String[] args) throws Exception {
Method method = String.class.getMethod("toUpperCase");
String result = (String) method.invoke("hello manbo~");
System.out.println(result); // HELLO MANBO~
}
}
进阶用法
🌈反射高级用法全景图
🕶动态代理篇
曼波觉得这就像给对象戴"智能眼镜"( •̀ ω •́ )✧
可以拦截方法调用并添加新功能!
核心代码示例
interface Animal {
void speak();
}
class Cat implements Animal {
public void speak() {
System.out.println("喵喵~");
}
}
// 代理工厂(重点!)
class ProxyFactory {
public static Object getProxy(Object target) {
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
(proxy, method, args) -> {
System.out.println("【前置通知】记录日志"); // 增强功能
Object result = method.invoke(target, args);
System.out.println("【后置通知】耗时统计");
return result;
}
);
}
}
// 使用示例
public static void main(String[] args) {
Animal cat = (Animal) new ProxyFactory().getProxy(new Cat());
cat.speak();
/* 输出:
【前置通知】记录日志
喵喵~
【后置通知】耗时统计 */
}
哦呜(°ロ°)!曼波觉得动态代理是框架的灵魂呢!(✪▽✪)曼波~~
🔖注解处理篇
曼波觉得注解就像给代码贴"智能标签"(ノ*・ω・)ノ
一起来制作属于自己的魔法标签吧!
自定义注解
@Retention(RetentionPolicy.RUNTIME) // 重要!运行时保留
@Target(ElementType.METHOD)
public @interface MyTest {
String value() default "默认测试";
int timeout() default 5;
}
注解处理器
class TestRunner {
public static void runTests(Object obj) throws Exception {
Class<?> clazz = obj.getClass();
for (Method method : clazz.getDeclaredMethods()) {
if (method.isAnnotationPresent(MyTest.class)) {
MyTest annotation = method.getAnnotation(MyTest.class);
System.out.println("🚀执行测试:" + annotation.value());
long start = System.currentTimeMillis();
method.invoke(obj);
long time = System.currentTimeMillis() - start;
if (time > annotation.timeout() * 1000) {
System.out.println("⚠️测试超时!预期:" + annotation.timeout() + "s");
}
}
}
}
}
// 使用示例
class MathTest {
@MyTest("加法测试")
public void testAdd() {
System.out.println("1+1=" + (1+1));
try { Thread.sleep(6000); } catch (InterruptedException e) {}
}
}
public static void main(String[] args) {
new TestRunner().runTests(new MathTest());
}
/* 输出:
🚀执行测试:加法测试
1+1=2
⚠️测试超时!预期:5s */
(✪▽✪)曼波~~!是不是很像JUnit的原理呢?接下来可以:
🎓学习建议
- 框架源码:看看Spring的@Autowired实现
- 实战练习:制作一个自动生成SQL语句的注解
- 性能优化:尝试用MethodHandle代替反射调用
- 安全实践:实现方法权限校验的代理