干活一年半了,准备还是整理一些文档吧,不然真的干了这么久活不知道自己干了啥(捂脸)
【资料图】
一方面也是因为我水平不如他人,一些东西做不到,很多时候我发现一些东西基本是我自己根本没有概念,但是意识到了以后学起来还是非常快的。
JavaPoet是一个例子。这个工具主要用途是提供Java代码的自动化生成。功能上比较轻量级,jar包放进来就能用。可以以接近原生代码书写的方式书写自动化代码。
项目页面:https://github.com/square/javapoet
直接在git上下载或者用maven都可以。
主要介绍读readme可以懂个大概。
我这里简单记录一下自己是怎么使用这个功能的。
一般构建java文件需要准备以下部分的代码:
FieldSpec:成员变量代码
样例:
可以生成:
MethodSpec: 成员方法代码
样例:
可以生成:
TypeSpec:类代码(基于MethodSpec和FieldSpec等)
样例:
将生成一个包含有之前样例成员变量与成员方法的类代码
JavaFile:java文件代码(基于TypeSpec)
样例:
生成的java文件将输出到src/my/pac/HelloClass.java
按顺序整理四个部分的代码,即可顺利完成java文件的自动生成。
使用过程中主要的关键字:
$T : 最重要的关键字,输出一个class,并且自动添加其import,可以直接使用当前代码里存在的class对象,也可以定义包名和类名来定义一个尚不存在的对象
使用例:
生成代码:
$N: 引用一个已经存在的JavaPoet相关对象,将其定义的name输出
使用例:
生成代码:
$L: 将指定的类型的string直接输出
$S: 将指定的类型包装成双引号string值输出
两者的区别可以通过以下使用例说明:
生成代码:
一些代码细节:
输出没有出现过的类:
使用ClassName.get方法,例如:
生成代码:
输出带有<T>模板相关的类:
生成代码:
应用场景:
1.使用AbstractProcessor进行注解预处理时,可以使用JavaPoet进行注解代码相关生成
似乎是网上常见的JavaPoet应用场景,我这里还在思考AbstractProcessor运行时不知道能不能获得足够的对象反射信息,准备后续学习;
如果是不太需要反射信息就能直接生成的代码,可以使用JavaPoet简单生成
2.直接写到项目代码里另开main方法进行代码生成。
我在现在的工作中是这么处理的,直接将JavaPoet生成代码的流程写到项目目录里,利用Class反射信息获取需要批量生成的Class对象反射信息(例如field,method,parameter等),生成相关代码写入到项目工程下。好处是可以直接利用工程代码反射信息,坏处是必须执行两遍java代码,第一遍是生成,第二遍是启动。
生成部分的代码可以分离,不在最终jar包里保存。
生成代码时如果产生了错误,可能导致后续build不能完全成功,可以调节运行模式在不全部通过编译时也能运行成功编译部分的class代码,在idea下,运行方法为在启动设置里设定“Build, no error check”来实现
我使用感觉JavaPoet的优点:轻量,生成代码直接简单,可以灵活应对各种代码生成需求
JavaPoet不能做到修改已有代码。JavaPoet只能生成新代码,不能改变已有的代码,也不能识别Java反射以外的信息。