🔍 Java反射与动态代理机制详解
一、反射机制(Reflection)
1.1 什么是反射?
反射是在运行时动态获取类的信息并操作类对象的能力。通过反射,我们可以在程序运行时:
- 获取类的Class对象
- 创建类的实例
- 调用类的方法
- 访问/修改类的字段
- 获取类的注解信息
1.2 核心API详解
1.2.1 获取Class对象的四种方式
// 方式1:通过类名.class(最安全,编译器检查)
Class<String> clazz1 = String.class;
// 方式2:通过对象.getClass()
String str = "hello";
Class<? extends String> clazz2 = str.getClass();
// 方式3:通过Class.forName()(最常用,可配置)
Class<?> clazz3 = Class.forName("java.lang.String");
// 方式4:通过ClassLoader.loadClass()
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
Class<?> clazz4 = classLoader.loadClass("java.lang.String");
1.2.2 创建实例的三种方式
Class<?> clazz = Class.forName("com.example.User");
// 方式1:使用newInstance()(已废弃,Java 9+)
// User user1 = (User) clazz.newInstance();
// 方式2:使用Constructor.newInstance()(推荐)
Constructor<?> constructor = clazz.getConstructor();
User user2 = (User) constructor.newInstance();
// 方式3:带参数的构造器
Constructor<?> paramConstructor = clazz.getConstructor(String.class, int.class);
User user3 = (User) paramConstructor.newInstance("张三", 25);
1.3 字段(Field)操作
public class User {
private String name;
public int age;
private static final String TAG = "User";
}
Class<User> clazz = User.class;
// 获取所有public字段(包括父类)
Field[] publicFields = clazz.getFields();
// 获取所有声明的字段(不包括父类)
Field[] declaredFields = clazz.getDeclaredFields();
// 获取特定字段
Field nameField = clazz.getDeclaredField("name");
Field ageField = clazz.getField("age");
// 设置访问权限(访问private字段需要)
nameField.setAccessible(true);
// 读取字段值
User user = new User("李四", 30);
String name = (String) nameField.get(user); // "李四"
// 修改字段值
nameField.set(user, "王五");
1.4 方法(Method)操作
public class Calculator {
public int add(int a, int b) {
return a + b;
}
private int multiply(int a, int b) {
return a * b;
}
}
Class<Calculator> clazz = Calculator.class;
// 获取所有public方法(包括父类方法)
Method[] publicMethods = clazz.getMethods();
// 获取所有声明的方法
Method[] declaredMethods = clazz.getDeclaredMethods();
// 获取特定方法
Method addMethod = clazz.getMethod("add", int.class, int.class);
Method multiplyMethod = clazz.getDeclaredMethod("multiply", int.class, int.class);
// 调用方法
Calculator calc = new Calculator();
Object result = addMethod.invoke(calc, 10, 20); // 30
// 调用私有方法
multiplyMethod.setAccessible(true);
Object multiplyResult = multiplyMethod.invoke(calc, 10, 20); // 200
// 调用静态方法
Method staticMethod = clazz.getMethod("staticMethod");
staticMethod.invoke(null); // 第一个参数为null表示静态方法
1.5 构造器(Constructor)操作
public class Person {
private String name;
public Person() {}
private Person(String name) {
this.name = name;
}
}
Class<Person> clazz = Person.class;
// 获取所有public构造器
Constructor<?>[] publicConstructors = clazz.getConstructors();
// 获取所有构造器(包括private)
Constructor<?>[] allConstructors = clazz.getDeclaredConstructors();
// 获取特定构造器
Constructor<Person> defaultConstructor = clazz.getConstructor();
Constructor<Person> privateConstructor = clazz.getDeclaredConstructor(String.class);
// 访问私有构造器
privateConstructor.setAccessible(true);
Person person = privateConstructor.newInstance("秘密人物");
1.6 反射性能优化技巧
// ❌ 错误的用法:每次调用都获取Method
for (int i = 0; i < 10000; i++) {
Method method = clazz.getMethod("methodName");
method.invoke(obj, args);
}
// ✅ 正确的用法:缓存Method
private static final Method CACHED_METHOD;
static {
try {
CACHED_METHOD = TargetClass.class.getMethod("methodName");
CACHED_METHOD.setAccessible(true);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// 使用时直接调用
CACHED_METHOD.invoke(obj, args);
二、动态代理(Dynamic Proxy)
2.1 什么是动态代理?
动态代理是在运行时创建代理类和代理对象的机制,主要用于AOP(面向切面编程)。
2.2 核心接口和类
// InvocationHandler - 代理调用的处理器接口
public interface InvocationHandler {
Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
}
// Proxy - 创建代理对象的工厂类
public class Proxy {
public static Object newProxyInstance(
ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h
);
}
2.3 动态代理实现步骤
2.3.1 定义接口和实现类
// 1. 定义接口
public interface IUserService {
void addUser(String username);
void deleteUser(String username);
String getUser(String username);
}
// 2. 实现类
public class UserServiceImpl implements IUserService {
@Override
public void addUser(String username) {
System.out.println("添加用户: " + username);
}
@Override
public void deleteUser(String username) {
System.out.println("删除用户: " + username);
}
@Override
public String getUser(String username) {
return "用户信息: " + username;
}
}
2.3.2 创建InvocationHandler
public class LogInvocationHandler implements InvocationHandler {
private final Object target; // 被代理的对象
public LogInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 前置增强
long startTime = System.currentTimeMillis();
System.out.println("方法调用开始: " + method.getName());
System.out.println("参数: " + Arrays.toString(args));
try {
// 调用原始方法
Object result = method.invoke(target, args);
// 后置增强
System.out.println("方法调用结束: " + method.getName());
System.out.println("返回值: " + result);
System.out.println("耗时: " + (System.currentTimeMillis() - startTime) + "ms");
return result;
} catch (Exception e) {
// 异常增强
System.err.println("方法调用异常: " + method.getName());
System.err.println("异常信息: " + e.getMessage());
throw e;
}
}
}
2.3.3 创建代理对象
public class ProxyFactory {
public static <T> T createProxy(T target, Class<T> interfaceClass) {
// 1. 创建InvocationHandler
InvocationHandler handler = new LogInvocationHandler(target);
// 2. 创建代理对象
return (T) Proxy.newProxyInstance(
target.getClass().getClassLoader(), // 类加载器
new Class<?>[]{interfaceClass}, // 代理接口
handler // InvocationHandler
);
}
}
// 使用示例
IUserService userService = new UserServiceImpl();
IUserService proxy = ProxyFactory.createProxy(userService, IUserService.class);
// 调用代理方法
proxy.addUser("张三");
// 输出:
// 方法调用开始: addUser
// 参数: [张三]
// 添加用户: 张三
// 方法调用结束: addUser
// 返回值: null
// 耗时: 5ms
2.4 动态代理源码分析
// Proxy.newProxyInstance()的核心逻辑(简化版):
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h) {
// 1. 生成代理类的字节码
byte[] proxyClassFile = generateProxyClass(interfaces);
// 2. 定义代理类
Class<?> proxyClass = defineClass0(loader, proxyClassFile);
// 3. 创建代理实例
Constructor<?> cons = proxyClass.getConstructor(InvocationHandler.class);
return cons.newInstance(h);
}
// 生成的代理类大致结构如下:
public final class $Proxy0 extends Proxy implements IUserService {
private static Method m1; // addUser方法
private static Method m2; // deleteUser方法
private static Method m3; // getUser方法
static {
try {
m1 = Class.forName("IUserService").getMethod("addUser", String.class);
m2 = Class.forName("IUserService").getMethod("deleteUser", String.class);
m3 = Class.forName("IUserService").getMethod("getUser", String.class);
} catch (Exception e) {
throw new Error(e);
}
}
public $Proxy0(InvocationHandler h) {
super(h);
}
@Override
public void addUser(String username) {
try {
h.invoke(this, m1, new Object[]{username});
} catch (Throwable e) {
throw new UndeclaredThrowableException(e);
}
}
// 其他方法类似...
}
2.5 动态代理的限制和解决方案
限制1:只能代理接口
// ❌ 不能直接代理类
UserServiceImpl target = new UserServiceImpl();
// UserServiceImpl proxy = (UserServiceImpl) Proxy.newProxyInstance(...); // 编译错误
// ✅ 解决方案:使用CGLIB或ByteBuddy
public class CglibProxyFactory {
public static <T> T createProxy(T target) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
System.out.println("前置增强");
Object result = proxy.invokeSuper(obj, args);
System.out.println("后置增强");
return result;
}
});
return (T) enhancer.create();
}
}
限制2:性能问题
// 性能优化方案:缓存代理类
public class ProxyCache {
private static final Map<String, Class<?>> PROXY_CLASS_CACHE = new ConcurrentHashMap<>();
public static Object createProxy(Object target, Class<?>[] interfaces,
InvocationHandler handler) {
String cacheKey = generateCacheKey(interfaces);
Class<?> proxyClass = PROXY_CLASS_CACHE.computeIfAbsent(cacheKey, key -> {
return Proxy.getProxyClass(target.getClass().getClassLoader(), interfaces);
});
try {
Constructor<?> constructor = proxyClass.getConstructor(InvocationHandler.class);
return constructor.newInstance(handler);
} catch (Exception e) {
throw new RuntimeException("创建代理失败", e);
}
}
private static String generateCacheKey(Class<?>[] interfaces) {
return Arrays.stream(interfaces)
.map(Class::getName)
.sorted()
.collect(Collectors.joining(","));
}
}
三、在Android Framework中的应用
3.1 Activity的反射实例化
// Android系统中Activity的创建过程
public Activity instantiateActivity(ClassLoader cl, String className, Intent intent)
throws Exception {
// 1. 通过类名加载Class
Class<?> clazz = cl.loadClass(className);
// 2. 创建Activity实例
Activity activity = (Activity) clazz.newInstance();
// 3. 调用attach方法
activity.attach(context, ...);
return activity;
}
3.2 Binder机制的动态代理
// AIDL生成的代理类就是动态代理的应用
public interface IMyService extends IInterface {
void doSomething();
}
// 系统生成的Stub和Proxy
public abstract class MyServiceStub extends Binder implements IMyService {
// ... Stub实现
// 客户端使用的Proxy类
private static class Proxy implements IMyService {
private IBinder mRemote;
Proxy(IBinder remote) {
mRemote = remote;
}
@Override
public void doSomething() {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
try {
data.writeInterfaceToken(DESCRIPTOR);
// 通过Binder发送数据
mRemote.transact(TRANSACTION_doSomething, data, reply, 0);
reply.readException();
} finally {
data.recycle();
reply.recycle();
}
}
}
}
3.3 Hook技术的应用
// Hook Activity启动过程的示例
public class HookManager {
public static void hookActivityManager() {
try {
// 1. 获取ActivityManagerNative的Class
Class<?> amnClass = Class.forName("android.app.ActivityManagerNative");
// 2. 获取gDefault字段
Field gDefaultField = amnClass.getDeclaredField("gDefault");
gDefaultField.setAccessible(true);
Object gDefault = gDefaultField.get(null);
// 3. 获取IActivityManager实例
Class<?> singletonClass = Class.forName("android.util.Singleton");
Field mInstanceField = singletonClass.getDeclaredField("mInstance");
mInstanceField.setAccessible(true);
Object rawIActivityManager = mInstanceField.get(gDefault);
// 4. 创建代理对象
Class<?> iActivityManagerInterface = Class.forName("android.app.IActivityManager");
Object proxy = Proxy.newProxyInstance(
Thread.currentThread().getContextClassLoader(),
new Class<?>[] { iActivityManagerInterface },
new IActivityManagerHandler(rawIActivityManager)
);
// 5. 替换原对象
mInstanceField.set(gDefault, proxy);
} catch (Exception e) {
e.printStackTrace();
}
}
static class IActivityManagerHandler implements InvocationHandler {
private Object mBase;
public IActivityManagerHandler(Object base) {
mBase = base;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 拦截startActivity方法
if ("startActivity".equals(method.getName())) {
// 修改参数,实现插件化等需求
// ...
}
// 调用原始方法
return method.invoke(mBase, args);
}
}
}
四、实践项目:实现一个简单的AOP框架
// 1. 定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Log {
String value() default "";
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Performance {
}
// 2. 创建切面处理器
public class AspectHandler implements InvocationHandler {
private Object target;
private Map<Method, List<MethodAdvice>> adviceMap = new HashMap<>();
public AspectHandler(Object target) {
this.target = target;
scanAdvices();
}
private void scanAdvices() {
Class<?> clazz = target.getClass();
for (Method method : clazz.getDeclaredMethods()) {
List<MethodAdvice> advices = new ArrayList<>();
// 检查Log注解
if (method.isAnnotationPresent(Log.class)) {
advices.add(new LogAdvice());
}
// 检查Performance注解
if (method.isAnnotationPresent(Performance.class)) {
advices.add(new PerformanceAdvice());
}
if (!advices.isEmpty()) {
method.setAccessible(true);
adviceMap.put(method, advices);
}
}
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
List<MethodAdvice> advices = adviceMap.get(method);
// 执行前置通知
if (advices != null) {
for (MethodAdvice advice : advices) {
advice.before(target, method, args);
}
}
Object result;
try {
// 执行目标方法
result = method.invoke(target, args);
// 执行后置通知
if (advices != null) {
for (MethodAdvice advice : advices) {
advice.afterReturning(target, method, args, result);
}
}
} catch (Exception e) {
// 执行异常通知
if (advices != null) {
for (MethodAdvice advice : advices) {
advice.afterThrowing(target, method, args, e);
}
}
throw e;
} finally {
// 执行最终通知
if (advices != null) {
for (MethodAdvice advice : advices) {
advice.after(target, method, args);
}
}
}
return result;
}
}
// 3. 通知接口
public interface MethodAdvice {
void before(Object target, Method method, Object[] args);
void afterReturning(Object target, Method method, Object[] args, Object result);
void afterThrowing(Object target, Method method, Object[] args, Throwable t);
void after(Object target, Method method, Object[] args);
}
// 4. 日志通知实现
public class LogAdvice implements MethodAdvice {
@Override
public void before(Object target, Method method, Object[] args) {
Log annotation = method.getAnnotation(Log.class);
String message = annotation.value().isEmpty() ?
method.getName() + "方法开始执行" : annotation.value();
System.out.println("[LOG] " + message);
}
@Override
public void afterReturning(Object target, Method method, Object[] args, Object result) {
System.out.println("[LOG] " + method.getName() + "方法执行成功");
}
@Override
public void afterThrowing(Object target, Method method, Object[] args, Throwable t) {
System.out.println("[LOG] " + method.getName() + "方法执行失败: " + t.getMessage());
}
@Override
public void after(Object target, Method method, Object[] args) {
System.out.println("[LOG] " + method.getName() + "方法执行结束");
}
}
// 5. 使用示例
public class UserService {
@Log("用户登录")
@Performance
public boolean login(String username, String password) {
// 登录逻辑
return true;
}
@Log("获取用户信息")
public User getUserInfo(int userId) {
// 获取用户信息逻辑
return new User();
}
}
// 6. 测试
public class Main {
public static void main(String[] args) {
UserService userService = new UserService();
AspectHandler handler = new AspectHandler(userService);
UserService proxy = (UserService) Proxy.newProxyInstance(
userService.getClass().getClassLoader(),
userService.getClass().getInterfaces(),
handler
);
// 调用方法,自动应用切面
proxy.login("admin", "123456");
proxy.getUserInfo(1);
}
}
五、常见面试题及答案
Q1:反射的性能问题如何优化?
答案:
- 缓存反射结果(Method、Field、Constructor)
- 使用
setAccessible(true)避免安全检查 - 使用MethodHandle(Java 7+)
- 使用字节码生成库(如ASM、CGLIB)
Q2:动态代理和静态代理的区别?
答案:
| 特性 | 静态代理 | 动态代理 |
|---|---|---|
| 创建时机 | 编译期 | 运行期 |
| 代理类数量 | 每个目标类需要一个代理类 | 一个代理类处理多个接口 |
| 灵活性 | 低,需要手动编写代理类 | 高,可动态生成 |
| 维护成本 | 高 | 低 |
| 性能 | 稍好 | 稍差(首次创建代理类有开销) |
Q3:动态代理在Android中的应用场景?
答案:
- Retrofit网络库:通过动态代理创建API接口实例
- ARouter路由框架:通过动态代理实现组件通信
- 插件化框架:Hook系统服务,实现插件加载
- AOP框架:实现日志、权限检查、性能监控等
六、学习建议
- 动手实践:按照上面的代码示例逐行敲一遍
- 源码阅读:阅读Java的Proxy类和InvocationHandler源码
- 性能测试:编写测试代码比较反射、动态代理和直接调用的性能差异
- 框架学习:学习Spring、Retrofit等框架中如何应用动态代理
学习路线建议:
反射基础 → 动态代理 → Android Framework中的应用 →
AOP实现 → 性能优化 → 源码分析
记住,反射和动态代理是理解Android Framework很多机制的基础,尤其是在插件化、热修复、AOP等高级技术中。