JavaPoet的使用指南

  • 前言
  • JavaPoet的基本介绍
    • JavaPoet的小试牛刀
    • JavaPoet的常用类
    • JavaPoet的常用方法
      • 设置修饰关键字
      • 设置注解对象
      • 设置注释
    • JavaPoet生成类、接口、枚举对象
      • 继承、实现接口
      • 方法
      • 枚举
    • JavaPoet生成成员变量
      • 注解
      • 修饰符
      • 注释
      • 实例化
    • JavaPoet生成方法
      • 构造方法
      • 常规方法
      • 方法参数
      • 返回值
      • 方法体
      • 方法体模板
        • $T
        • $N
        • $S
      • 抛出异常
    • JavaPoet生成方法参数
      • 初始化ParameterSpec
      • 添加修饰符
      • 添加注解
    • JavaPoet生成注解
      • 初始化AnnotationSpec
      • 设置属性
    • JavaPoet如何生成代码
      • 打印结果
      • 生成文件
    • 结束语

前言

对于我来说,JavaPoet也是不经意间发现的,日常Android开发中:

主要使用Mvp+RxJava+Dagger2这套框架

在这套框架里每次写Activity或者Fragment就会写一套Mvp+Compent+Module,如下图:

经过长时间的重复编写,发现这一套Mvp+Compent+Module文件,只有名称是变化的,所以只需要将名称抽象出来,其他只需模板化,就能生成出上述Java文件.

正当想怎么能够快捷生成Java文件,这时JavaPoet便出现,而且JavaPoet能够完全满足需求。

本文主要以JavaPoet的使用方法介绍为主,会将JavaPoet的基本API都介绍一遍,你也可以理解成JavaPoet的中文简易教程

JavaPoet的基本介绍

(1)JavaPoet是一款可以自动生成Java文件的第三方依赖
(2)简洁易懂的API,上手快
(3)让繁杂、重复的Java文件,自动化生成,提高工作效率,简化流程

JavaPoet的小试牛刀

为了展示JavaPoet的能力,这里以自动生成一个全新的MainActivity为例。

public class MainActivity extends Activity{@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}
}

我在使用JavaPoet的时候,习惯从外向内逐一生成,但是这不是标准,这里可以按照自己的方式来理解和生成.

    public static void main(String[] args) {ClassName activity = ClassName.get("android.app", "Activity");TypeSpec.Builder mainActivityBuilder = TypeSpec.classBuilder("MainActivity").addModifiers(Modifier.PUBLIC).superclass(activity);ClassName override = ClassName.get("java.lang", "Override");ClassName bundle = ClassName.get("android.os", "Bundle");ClassName nullable = ClassName.get("android.support.annotation", "Nullable");ParameterSpec savedInstanceState = ParameterSpec.builder(bundle, "savedInstanceState").addAnnotation(nullable).build();MethodSpec onCreate = MethodSpec.methodBuilder("onCreate").addAnnotation(override).addModifiers(Modifier.PROTECTED).addParameter(savedInstanceState).addStatement("super.onCreate(savedInstanceState)").addStatement("setContentView(R.layout.activity_main)").build();TypeSpec mainActivity = mainActivityBuilder.addMethod(onCreate).build();JavaFile file = JavaFile.builder("com.test", mainActivity).build();try {file.writeTo(System.out);} catch (IOException e) {e.printStackTrace();}}

通过在Main方法中运行以上的代码,就可以直接生成出MainActivity对象,自上而下的观察上述代码,你会发现JavaPoet让java文件变得有逻辑性。

JavaPoet的常用类

  1. TypeSpec————用于生成类、接口、枚举对象的类
  2. MethodSpec————用于生成方法对象的类
  3. ParameterSpec————用于生成参数对象的类
  4. AnnotationSpec————用于生成注解对象的类
  5. FieldSpec————用于配置生成成员变量的类
  6. ClassName————通过包名和类名生成的对象,在JavaPoet中相当于为其指定Class
  7. ParameterizedTypeName————通过MainClass和IncludeClass生成包含泛型的Class
  8. JavaFile————控制生成的Java文件的输出的类

JavaPoet的常用方法

设置修饰关键字

addModifiers(Modifier... modifiers)

Modifier是一个枚举对象,枚举值为修饰关键字Public、Protected、Private、Static、Final等等。
所有在JavaPoet创建的对象都必须设置修饰符(包括方法、类、接口、枚举、参数、变量)。

设置注解对象

addAnnotation(AnnotationSpec annotationSpec)
addAnnotation(ClassName annotation)
addAnnotation(Class<?> annotation)

该方法即为类或方法或参数设置注解,参数即可以是AnnotationSpec,也可以是ClassName,还可以直接传递Class对象。
一般情况下,包含复杂属性的注解一般用AnnotationSpec,如果单纯添加基本注解,无其他附加属性可以直接使用ClassName或者Class即可。

设置注释

addJavadoc(CodeBlock block)
addJavadoc(String format, Object... args)

在编写类、方法、成员变量时,可以通过addJavadoc来设置注释,可以直接传入String对象,或者传入CodeBlock(代码块)。

JavaPoet生成类、接口、枚举对象

在JavaPoet中生成类、接口、枚举,必须得通过TypeSpec生成,而classBuilder、interfaceBuilder、enumBuilder便是创建其关键的方法:

创建类:
TypeSpec.classBuilder("类名“)
TypeSpec.classBuilder(ClassName className)创建接口:
TypeSpec.interfaceBuilder("接口名称")
TypeSpec.interfaceBuilder(ClassName className)创建枚举:
TypeSpec.enumBuilder("枚举名称")
TypeSpec.enumBuilder(ClassName className)

继承、实现接口

继承类:
.superclass(ClassName className)实现接口
.addSuperinterface(ClassName className)

继承存在泛型的父类

当继承父类存在泛型时,需要使用ParameterizedTypeName

ParameterizedTypeName get(ClassName rawType, TypeName... typeArguments)

返回的ParameterizedTypeName对象,已经被添加泛型信息

方法

addMethod(MethodSpec methodSpec)

通过配置MethodSpec对象,使用addMethod方法将其添加进TypeSpec中。

枚举

addEnumConstan(String enumValue)

通过addEnumConstan方法添加枚举值,参数为枚举值名称。

JavaPoet生成成员变量

JavaPoet生成成员变量是通过FieldSpec的build方法生成.

builder(TypeName type, String name, Modifier... modifiers)

只要传入TypeName(Class)、name(名称)、Modifier(修饰符),就可以生成一个基本的成员变量。

成员变量一般来说由注解(Annotation)、修饰符(Modifier)、Javadoc(注释)、initializer(实例化)。

注解

addAnnotation(TypeName name)

修饰符

addModifiers(Modifier ...modifier)

注释

addJavadoc(String format, Object... args)

由于上述三个方法,都在通用方法介绍过这里就不再重复介绍。

实例化

initializer(String format, Object... args)

即成员变量的实例化,例:

public Activity mActivity = new Activity;

initializer方法中的内容就是“=”后面的内容,下面看下具体的代码实现,上面的成员变量:

  ClassName activity = ClassName.get("android.app", "Activity");FieldSpec spec = FieldSpec.builder(activity, "mActivity").addModifiers(Modifier.PUBLIC).initializer("new $T", activity).build();

JavaPoet生成方法

JavaPoet生成方法分为两种,第一种是构造方法,另一种为常规的方法。

构造方法

MethodSpec.constructorBuilder()

常规方法

MethodSpec.methodBuilder(String name)

方法的主要构成有方法参数、注解、返回值、方法体、抛出异常五种,注解可以参考通用方法addAnnotation,其他方法我们将会一一介绍:

方法参数

addParameter(ParameterSpec parameterSpec)

设置方法参数的方法通过addParameterSpec来实现,ParameterSpec的具体使用参考下一小节。

返回值

returns(TypeName returnType)

设置方法的返回值,只需传入一个TypeName对象,而TypeName是ClassName,ParameterizedTypeName的基类。

方法体

在JavaPoet中,设置方法体内容有两个方法,分别是addCode和addStatement:

addCode()addStatement()

这两个本质上都是设置方法体内容,但是不同的是使用addStatement()方法时,你只需要专注于该段代码的内容,至于结尾的分号和换行它都会帮你做好。
而addCode()添加的方法体内容就是一段无格式的代码片,需要开发者自己添加其格式。

方法体模板

在JavaPoet中,设置方法体使用模板是比较常见的,因为addCode和addStatement方法都存在这样的一个重载:

addCode(String format, Object... args)addStatement(String format, Object... args)

在JavaPoet中,format中存在三种特定的占位符:

$T

$T 在JavaPoet代指的是TypeName,该模板主要将Class抽象出来,用传入的TypeName指向的Class来代替。

ClassName bundle = ClassName.get("android.os", "Bundle");
addStatement("$T bundle = new $T()",bundle)

上述添加的代码内容为:

Bundle bundle = new Bundle();
$N

$N在JavaPoet中代指的是一个名称,例如调用的方法名称,变量名称,这一类存在意思的名称

addStatement("data.$N()",toString)

上述代码添加的内容:

data.toString();
$S

S在JavaPoet中就和String.format中S在JavaPoet中就和String.format中%s一样,字符串的模板,将指定的字符串替换到S在JavaPoet中就和String.format中S的地方,需要注意的是替换后的内容,默认自带了双引号,如果不需要双引号包裹,需要使用$L.

.addStatement("return $S", “name”)

即将"name"字符串代替到$S的位置上.

抛出异常

.addException(TypeName name)

设置方法抛出异常,可以使用addException方法,传入指定的异常的ClassName,即可为该方法设置其抛出该异常.

JavaPoet生成方法参数

JavaPoet生成有参方法时,需要填充参数,而生成参数则需要通过ParameterSpec这个类。

addParameter(ParameterSpec parameterSpec)

初始化ParameterSpec

ParameterSpec.builder(TypeName type, String name, Modifier... modifiers)

给参数设置其Class,以及参数名称,和修饰符.

通常来说参数的构成包括:参数的类型(Class)、参数的名称(name)、修饰符(modifiers)、注解(Annotation)

除了builder方法初始化类型、以及名称、修饰符之外,其余可以通过如下方法进行设置:

添加修饰符

.addModifiers(Modifier modifier)

添加注解

addAnnotation(TypeName name)

添加修饰符、注解具体使用可参考通用方法。

JavaPoet生成注解

在JavaPoet创建类、成员变量、方法参数、方法,都会用到注解。

如果使用不包含属性的注解可以直接通过

   .addAnnotation(TypeName name)

直接传入TypeName或者Class进行设置。

如果使用的注解包含属性,并且不止一个时,这时候就需要生成AnnotationSpec来解决,下面简单了解下AnnotationSpec。

初始化AnnotationSpec

AnnotationSpec.builder(ClassName type)

可以发现初始化,只需传入ClassName或者Class即可。

设置属性

addMember(String name, String format, Object... args)

使用addMember可以设置注解的属性值,name对应的就是属性名称,format的内容即属性体,同样方法体的格式化在这里也是适用的。

JavaPoet如何生成代码

如果上述内容你已经看完,那么恭喜你,你已经明白JavaPoet的意图,但是现在的你,还差最后一步,即如何生成代码。

JavaPoet中负责生成的类是JavaFile

JavaFile.builder(String packageName, TypeSpec typeSpec)

JavaFile通过向build方法传入PackageName(Java文件的包名)、TypeSpec(生成的内容)生成。

打印结果

javaFile.writeTo(System.out)

生成的内容会输出到控制台中

生成文件

javaFile.writeTo(File file)

生成的内容会以java文件的方式,存放到你传入File文件的位置

结束语

当你读完了本文,如果你产生下面的想法:

  1. JavaPoet原来还可以这样
  2. JavaPoet编写过程为什么那么流畅,原来Java文件也可以用编程的方式生成
  3. JavaPoet可不可以改进我的编码流程,提升效率

那么说明你已经对JavaPoet感兴趣了,可以自己动手尝试一下,感受下JavaPoet的魅力。

最后贴一张,JavaPoet秘籍,有了它会很好的帮助你使用JavaPoet.

(注明:该图来自walfud的个人博客)

上面的博客无法访问,这是掘金的转载

JavaPoet的使用指南相关推荐

  1. 太赞了!靠这份Android知识点PDF成功跳槽,使用指南

    前言 相信很多同学都会有这样的感受,前三天刚刚复习的知识点,今天问的时候怎么就讲不出个所以然了呢? 本文的目的就是致力于帮助大家尽可能的建立Android知识体系,希望大家会喜欢~ 目录: 1.网络 ...

  2. 超详细中文预训练模型ERNIE使用指南-源码

    作者 | 高开远,上海交通大学,自然语言处理研究方向 最近在工作上处理的都是中文语料,也尝试了一些最近放出来的预训练模型(ERNIE,BERT-CHINESE,WWM-BERT-CHINESE),比对 ...

  3. 入门指南目录页 -PaddlePaddle 飞桨 入门指南 FAQ合集-深度学习问题

    入门指南目录页 -PaddlePaddle 飞桨 入门指南 FAQ合集 GT_Zhang关注 0.1012019.08.01 18:43:34字数 1,874阅读 795 Hi,欢迎各位来自Paddl ...

  4. ASIC设计-终极指南

    ASIC设计-终极指南 ASIC Design – The Ultimate Guide ASIC设计-终极指南 ASICs代表特定于应用的集成电路,指的是针对特定应用而设计的半导体解决方案,与其他解 ...

  5. Python神经网络集成技术Guide指南

    Python神经网络集成技术Guide指南 本指南将介绍如何加载一个神经网络集成系统并从Python运行推断. 提示 所有框架的神经网络集成系统运行时接口都是相同的,因此本指南适用于所有受支持框架(包 ...

  6. 深度学习框架集成平台C++ Guide指南

    深度学习框架集成平台C++ Guide指南 这个指南详细地介绍了神经网络C++的API,并介绍了许多不同的方法来处理模型. 提示 所有框架运行时接口都是相同的,因此本指南适用于所有受支持框架(包括Te ...

  7. HTML5与CSS3权威指南之CSS3学习记录

    title: HTML5与CSS3权威指南之CSS3学习记录 toc: true date: 2018-10-14 00:06:09 学习资料--<HTML5与CSS3权威指南>(第3版) ...

  8. Maven入门指南⑦:Maven的生命周期和插件

    Maven入门指南⑦:Maven的生命周期和插件 一个完整的项目构建过程通常包括清理.编译.测试.打包.集成测试.验证.部署等步骤,Maven从中抽取了一套完善的.易扩展的生命周期.Maven的生命周 ...

  9. ini文件怎么使用_ftp文件下载工具,ftp文件下载工具是怎么使用的?使用指南

    ftp文件下载工具是什么工具,可能有人会回答说不知道,因为一般只有从事网站管理的工作者会使用的多一点.但不是每个人生来就会的,所以刚开始肯定都会学习怎么使用.这篇文章就来教一下大家ftp文件下载工具是 ...

最新文章

  1. linux服务器root的密码修改
  2. PIX failover+负载
  3. STm32 使用 stm32cube GPIO 点亮 led 的
  4. zabbix 2.2 监控mysql_Zabbix-2.2.2监控MySQL的复制-阿里云开发者社区
  5. C# asp:Repeater DataSource ListT
  6. 借助opencv将unsigned char数组显示为图像
  7. java mybatis 返回map_mybatis返回map集合的格式是什么?mybatis返回map集合实例
  8. mysql 创建聚集索引_索引为什么会加快Mysql的查询速度?
  9. 值得收藏的130个神器网站
  10. HCNP学习笔记:OSPF报头及各种报文格式
  11. smart原则_真正的有效目标--SMART原则
  12. 【硬件和驱动】如何查看linux的驱动有没有装好 ——声卡无声音,有驱动为例子,网卡wifi驱动相关
  13. 如何查看内存条的实际使用频率
  14. 多目标人工秃鹫优化算法(MATLAB源码分享,智能优化算法) 提出了一种多目标版本的人工秃鹫优化算法(AVOA)
  15. 复杂大脑网络的结构和功能
  16. 52GB!网曝网易邮箱数据又泄露?还是葫芦娃?
  17. Visual Studio点击之前创建的Form提示“由于从未加载设计器的文档,因此无法显示设计器”
  18. OSI七层模型及其功能
  19. 数据存储大讲堂:谈磁盘列阵与RAID技巧
  20. Android中android:digits限制无效原因

热门文章

  1. 我的时间都去哪里了?
  2. 从孙子兵法看企业价值观和企业文化
  3. 自制合成孔径雷达(7) 声卡实现测速声呐
  4. 虚拟机Vmware安装Ubuntu系统
  5. 51单片机4G模块通信(EC03-DNC4G)
  6. 性能监控工具-----ServerAgent
  7. 解决微信小程序“app.json: [“workers“] 字段需为 目录“错误及worker的使用
  8. fread函数 和 feof函数
  9. C# : 软件加密机制以及如何防止反编译
  10. Mybatis-主键回填