重走安卓进阶路

重走安卓进阶路——反射及动态代理模式

2020-03-09  本文已影响0人  小呀么小黄鸡
  1. 什么是反射:正常使用一个类,可以直接对他实例化(new),之后直接操作这个对象实例,而反射中,我们使用JDK提供的API对不特定的类进行实例化——<1>只有在运行时才知道要操作的类(需要对得到的不确定类进行强制类型转换);<2>能在运行时完整地获取类的构造,并调用其方法
  2. Class中有什么
    编译器将我们编写的java文件和Class.java一起编译成.class文件。将类的元数据信息放在.class文件末尾,虚拟机中对一个类的定义只会有一份,如果没有则先读出class文件,再进行new操作(实例化)
    Class中包括了Field、Method和Constructor。
  3. 反射怎么用
    获取一个类的class的三种方法:

反射在运行时才去生成、加载、调用这个class文件,因此效率比正常的new低


代理模式那些事

定义

给目标对象提供一个代理对象,并由代理对象控制对目标对象的引用

目的

  1. 通过引入代理对象来间接访问目标对象,防止直接访问带来不必要的复杂性
  2. 通过代理对象对原有的业务增加,但都包含同样的接口
    静态代理,违反开闭原则,扩展能力差,可维护性差
    动态代理,在使用时再创建代理类和实例,要用反射机制,效率比静态低,使用场景受限(Java单继承,只对接口代理)
    <1>Proxy 主体(产生动态代理对象)
    <2>InvocationHandler 事务处理

代理类实现Proxy.newProxyInstance,通过getProxyInstance给外部类调用,代理实现InvocationHandler,类似于拦截。
如果打印出生成的字节数组到.class文件并反编译,可以看到动态代理生成的类,以Proxy为父类,实现了需要代理的接口(Proxy+InvocationHandler)

Retrofit

它是网络请求的适配器,可以吧Java的接口翻译成http请求,通过okhttp去发送请求
步骤是:

  1. 创建一个接口文件,通过注解声明需要用到的请求的信息;
  2. 使用Retrofit的构造器创建一个实例;
  3. 用Retrofit实例的create方法创建出了接口的示例;
  4. 在业务中调用接口文件中的方法进行请求。
    其中第三步就使用了动态代理创建了接口的代理类与实例,完成了其中的事务处理(InvocationHandler)。

建议

可以通过静态代理的实现和动态代理的实现进行实操了解

答疑

  1. 静态代理使用的场景很少(除非使用的场景很少且不考虑再扩展),绝大部分都是用的动态代理
  2. 对newProxyInstance传入的interfaces数组进行了clone,是因为Java是传值引用,通过方法传入的interfaces变量只是它的引用,通过clone这个变量并用final修饰它,避免内部修改对外部数组的影响

ps.原来的标题

上一篇 下一篇

猜你喜欢

热点阅读