前言;
本篇为 Android 架构师 java 原理专题二; 反射原理及动态代理模式.
大公司面试都要求我们有扎实的 Java 语言基础. 而很多 Android 开发朋友这一块并不是很熟练, 甚至半路初级底子很薄, 这给我们进阶造成了很大的困扰, 很容易就碰到瓶颈. 如果我们想提升成为高级工程师甚至架构师, java 基础一定要学好.
一. 反射(Reflect)
反射之中包含了一个「反」字, 所以了解反射我们先从「正」开始.
一般情况下, 我们使用某个类时必定知道它是什么类, 是用来做什么的. 于是我们直接对这个类进行实例化, 之后使用这个类对象进行操作.
反射则是一开始并不知道我要初始化的类对象是什么, 自然也无法使用 new 关键字来创建对象了. 这时候, 我们使用 JDK 提供的反射 API 进行反射调用. 反射就是在运行时才知道要操作的类是什么, 并且可以在运行时获取类的完整构造, 并调用对应的方法.
Reflection(反射)是 Java 被视为动态语言的关键, 反射机制允许程序在执行期借助于 Reflection API 取得任何类的內部信息, 并能直接操作任意对象的内部属性及方法.
Java 反射机制主要提供了以下功能:
在运行时构造任意一个类的对象
在运行时获取任意一个类所具有的成员变量和方法
在运行时调用任意一个对象的方法(属性)
Java 是一门面向对象的语言. 在面向对象的世界里, 万事万物皆对象, 既然万事万物皆对象, 那么我们的类是不是对象呢?
我们写的每一个类都可以看成一个对象, 是 java.lang.Class 类的对象. 每一个类对应的 Class 放在哪里呢? 当我们写完一个类的 Java 文件, 编译成 class 文件的时候, 编译器都会将这个类的对应的 class 对象放在 class 文件的末尾.
里面都保存了些什么? 大家可以理解保存了类的元数据信息, 一个类的元数据信息包括什么? 有哪些属性, 方法, 构造器, 实现了哪些接口等等, 那么这些信息在 Java 里都有对应的类来表示.
Class 类
Class 是一个类, 封装了当前对象所对应的类的信息
一个类中有属性, 方法, 构造器等, 比如说有一个 Person 类, 一个 Order 类, 一个 Book 类, 这些都是不同的类, 现在需要一个类, 用来描述类, 这就是 Class, 它应该有类名, 属性, 方法, 构造器等. Class 是用来描述类的类.
Class 类是一个对象照镜子的结果, 对象可以看到自己有哪些属性, 方法, 构造器, 实现了哪些接口等等
对于每个类而言, JRE 都为其保留一个不变的 Class 类型的对象. 一个 Class 对象包含了特定某个类的有关信息.
对象只能由系统建立对象, 一个类 (而不是一个对象) 在 JVM 中只会有一个 Class 实例
获取 Class 对象的三种方式;
1. 通过类名获取 类名. class
2. 通过对象获取 对象名. getClass()
3. 通过全类名获取 Class.forName(全类名)
二. 动态代理
代理模式和静态代理
代理模式给某一个对象提供一个代理对象, 并由代理对象控制对原对象的引用. 通俗的来讲代理模式就是我们生活中常见的中介.
举个例子来说明: 张三想买某种用品, 虽然他可以自己去找, 但是这确实太浪费时间和精力了, 或者不好意思去买. 于是张三就通过中介 Mark 来买, Mark 来帮张三, 张三只是负责选择自己喜欢的的 size, 然后付钱就可以了.
目的:
(1)通过引入代理对象的方式来间接访问目标对象, 防止直接访问目标对象给系统带来的不必要复杂性
(2)通过代理对象对原有的业务增强;
代理模式一般会有三个角色:
抽象角色: 指代理角色和真实角色对外提供的公共方法, 一般为一个接口
真实角色: 需要实现抽象角色接口, 定义了真实角色所要实现的业务逻辑, 以便供代理角色调用. 也就是真正的业务逻辑在此.
代理角色: 需要实现抽象角色接口, 是真实角色的代理, 通过真实角色的业务逻辑方法来实现抽象方法, 并可以附加自己的操作. 将统一的流程控制都放到代理角色中处理!
而访问者不再访问真实角色, 而是去访问代理角色.
静态代理在使用时, 需要定义接口或者父类, 被代理对象与代理对象一起实现相同的接口或者是继承相同父类. 一般来说, 被代理对象和代理对象是一对一的关系, 当然一个代理对象对应多个被代理对象也是可以的.
静态代理, 一对一则会出现时静态代理对象量多, 代码量大, 从而导致代码复杂, 可维护性差的问题, 一对多则代理对象会出现扩展能力差的问题.
三. 动态代理
是指在使用时再创建代理类和实例
优点
只需要 1 个动态代理类就可以解决创建多个静态代理的问题, 避免重复, 多余代码
更强的灵活性
缺点
效率低, 相比静态代理中 直接调用目标对象方法, 动态代理则需要先通过 Java 反射机制 从而 间接调用目标对象方法
应用场景局限, 因为 Java 的单继承特性(每个代理类都继承了 Proxy 类), 即只能针对接口 创建 代理类, 不能针对类创建代理类.
在 java 的动态代理机制中, 有两个重要的类或接口, 一个是 InvocationHandler 接口, 另一个则是 Proxy 类, 这个类和接口是实现我们动态代理所必须用到的.
InvocationHandler 接口是给动态代理类实现的, 负责处理被代理对象的操作的, 而 Proxy 是用来创建动态代理类实例对象的, 因为只有得到了这个对象我们才能调用那些需要代理的方法.
四. 总结
以上为概念介绍, 建议理解概念后再去学习动态代理实现原理, 原理详解视频也可以分享给大家, 有兴趣的朋友记得把自己去理解其中原理, 并且手写一下源码, 依靠复制粘贴是永远不会有大的成长的
五. BAT 主流 Android 架构技术大纲 + 学习路线 + 全套视频;
架构技术详解和学习路线与资料分享请看这篇;《BATJ 一线大厂最主流的 Android 高级架构技术; 体系详解 + 学习路线》
(包括自定义控件, NDK, 架构设计, 混合式开发工程师(React native,Weex), 性能优化, 完整商业项目开发等)
阿里 P8 级 Android 架构师技术脑图;
全套体系化高级架构视频; 七大主流技术模块, 视频 + 源码 + 笔记
来源: http://www.jianshu.com/p/d1a261111279