记录反射与动态代理相关的知识点
反射api记录:
https://www.jianshu.com/p/e55770dd48d3
setAccessible(boolean flag) //true表示取消访问权限检查
含有Declared的,可以获取所有权限
非Declared的,只能获取public
Class对象
//第一种方式 通过Class类的静态方法——forName()来实现
class1 = Class.forName(“com.lvr.reflection.Person”);
//第二种方式 通过类的class属性
class1 = Person.class;
//第三种方式 通过对象getClass方法
Person person = new Person();
Class<?> class1 = person.getClass();
获取 Class 对应类的成员变量
Field[] getDeclaredFields();
// 获取 Class 对象对应类的所有属性,与成员变量的访问权限无关。
Field getDeclaredField(String name);
// 获取 Class 对象对应类的指定名称的属性,与成员变量的访问权限无关。
Field[] getFields();
// 获取 Class 对象对应类的所有 public 属性
Field getField(String name);
// 获取 Class 对象对应类的指定名称的 public 属性。
获取 Class 对应类的方法
Method[] getDeclaredMethods();
// 获取 Class 对象对应类的所有声明方法,于方法的访问权限无关。
Method getDeclaredMethod(String name, Class>...parameterTypes);
// 返回此 Class 对象对应类的、带指定形参列表的方法,与方法的访问权限无关。
Method[] getMethods();
// 获取 Class 对象对应类的所有 public 方法,包括父类的方法。
Method getMethod(String name, Class>…parameterTypes);
// 返回此 Class 对象对应类的、带指定形参列表的 public 方法。
创建对象
1.使用 Class 对象的 newInstance() 方法(要求:Class 对象的对应类要有默认构造器)
2.先使用 Class 对象获取指定的 Constructor 对象,再调用 Constructor 对象的 newInstance() 方法(这种方式可以选择使用指定的构造器来创建实例。)
调用方法
method.invoke(Object obj, Object… args)
obj是method的调用者,args是method的参数
获取对象xxx
field.get(A)//field是A的普通变量
field.get(null)//field是A的静态变量
替换对象
field.set(obj,newValue)//field是obj对象的属性/变量
动态代理:
https://juejin.cn/post/7275185537815183360
https://juejin.cn/post/6844903978342301709
动态代理是一种通过创建代理对象来代替原始对象的技术,以便在方法调用前后执行额外的操作。代理对象通常实现与原始对象相同的接口,但可以添加自定义行为。动态代理是在运行时生成的,因此它不需要在编译时知道原始对象的类型。
通过反射机制动态生成代理者对象的一种设计模式。
1 | Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h); |
1 | //回调h的invoke方法 |
1 | //在上述方法中 |
可以在上述第三步的前后分别执行自定义的逻辑
详细代码可以查看 kotlinbox
如何区分静态代理和动态代理?
- 静态代理:程序运行前,代理类已经存在。
- 动态代理:程序运行前,代理类不存在,运行过程中,动态生成代理类。
动态代理的好处
1 | // 接口 |
静态代理类实现一样的接口,持有被代理类的实例A,再用A去调方法
如果接口发生变化,则静态代理类实现就要修改或者新增代理类
动态代理不需要修改,运行时生成代理类
只需要1个动态代理类就可以解决创建多个静态代理的问题,避免重复、多余代码
动态代理和反射
反射和动态代理都是在运行时处理类和对象的技术,但它们的应用场景不同。反射主要用于在运行时检查和操作类的信息,而动态代理主要用于在方法调用前后执行额外的逻辑。选择使用哪种技术取决于你的具体需求和设计目标。