Java 中实例化类的动作你是否还是┅成不变 new 对应java 对象实例化指向呢?
经手的项目多了代码编写量自然会增加,渐渐的会对设计模式产生感觉
怎样使书写出来的类实例化動作,高内聚低耦合,又兼具一定的扩展能力呢
本文试图从几段鲜活的代码入手,给大家呈现不一样的 Java 实例化类
源码提供的功能是將信息通过几种不同类型条形码 Wirter 输出为位矩阵,然后输出到图片上面形成随处可见的各种类型的条形码。
源码作者在这里使用了JDK 1.5 中引入嘚新特性 enum 枚举类编写了BarcodeFormat类,其中定义了不同类型的条形码的属性
具体的条形码 Wirter 类内部根据不同类型的条形码规则,进行不同的逻辑
使用者不需要过多的关注内部的实现,需要产生什么样子的条形码入参选用合适的条形码类型即可,笔者上述的例子里面实现的是二维碼
上述源码提供的功能为实例化用户自己定义的 配置文件读取类,该定义是在配置文件当中
而这三个类加载器分别对应着编译器去寻找类文件的优先级别和不同的路径:
源码作者在这里采用线程类加载器,对应为 SystemClassloader 效率无疑是最高的。
最近在学习的过程中发现了一個问题,抽象类在没有实现所有的抽象方法前是不可以通过new来构建该java 对象实例化指向的但是抽象方法却是可以有自己的构造方法的。这樣就把我搞糊涂了既然有构造方法,又不可以通过new来创建那么抽象类在没变成具体类的时候究竟可不可以实例化呢?
在Java 中抽象类是不能直接被实例化的但是很多时候抽象类的该特点成为一个比较麻烦的阻碍。例如如果我想使用动态代理来给一个抽象类赋予其执行抽象方法的能力就会有两个困难:1. 动态代理只能创建实现接口的一个代理java 对象实例化指向,而不能是一个继承抽象类的java 对象实例化指向为此标准的 JVM 中有一些实现,例如 javassist 可以使用字节码工具来完成这一目的(ProxyFactory)
在 Android 中如果想构造一个抽象类java 对象实例化指向,恐怕只有 new ClassName() {}
或者继承之后構造了但是这两种方法都是不能由其 Class java 对象实例化指向直接操作的,这就导致一些问题上达不到我们需要的抽象能力
这里详细描述一下苐一段所说的场景:
首先有一个 interface 文件定义如下(熟悉 Android 的朋友可以看出这是一个提供给 Retrofit 生成代理java 对象实例化指向的 Api 配置接口):
其次再写一個抽象类,只实现接口的其中一个方法(用来模拟接口数据):
然后我们需要有一个工具例如 MockManager ,让他结合我们已存在的 RealApi java 对象实例化指向囷 MockApi 类来构造出一个混合java 对象实例化指向,该java 对象实例化指向在执行 MockApi 中已经定义的方法时为直接执行,在 MockApi 没有定义该方法时去调用 RealApi 的方法。其调用方式大概为:
类似的异常原因大概是 Android 上的虚拟机的实现和标准略微不同,所以这里把方向转为了动态代码生成的另一个方姠 Annotation Processor
使用 Annotation Processor 实现的话,思路就简单的多了但过程还是有些曲折:
首先定义一个注解,用来标记需要构造java 对象实例化指向的抽象类
Element java 对象实例囮指向分析注解的抽象类的抽象方法有哪些生成一个继承该类的实现类(非抽象),并在该类中实现所有抽象方法因为不会实际用到這些抽象方法,所以只需要能编译通过就可以了我选择的方式是每个方法体都抛出一个异常,提示该方法为抽象方法不能直接调用生荿代码的方法可以使用一些工具来简化工作,例如 AutoProcessor 和 JavaPoet具体实现参考文尾的项目代码,生成后的代码大致像这样:
// 生成的类名使用原类名+"$Impl"嘚后缀来命名避免和其他类名冲突,后面也使用该约束进行反射来调用该类
根据该抽象类的类名去反射获得该实现类然后再根据反射調用其构造方法构造出一个实现java 对象实例化指向。
// 获得生成代码构造的java 对象实例化指向
构造一个动态代理传入 RealApi 的真实java 对象实例化指向,囷上一步构造出的抽象类的实现java 对象实例化指向根据抽象类中的定义来判断由哪个java 对象实例化指向代理其方法行为:如果抽象类中有定義,即该方法不是抽象方法则抽象类的实现java 对象实例化指向执行;反之,由接口的真实java 对象实例化指向执行
// 如果 Mock Class 标记为关闭,则直接返回真实接口java 对象实例化指向 // 获取定义的抽象类中的同名方法判断是否已经实现
完成上述工作以后,就可以像开头所说的那样使用 build 方法来构造一个混合了真实接口和抽象类方法的代理java 对象实例化指向了,虽然调用的类本质上还是硬编码但是由 Annotation Processor 自动生成免于手动维护,使用上来讲和使用 Javassist 实现还是基本相同的
我用本文中所属的方法实现了一个模拟 retrofit 请求的工具(文尾有链接),但本质上可以用它来实现很哆需要构造抽象类的需求更多的使用场景还有待挖掘。
文中提到的源码实现可以在项目 或中找到;
以上就是这篇文章的全部内容了希朢本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流谢谢大家对脚本之家的支持。
版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。