javapoet动态生成java代码
刚接触第一感觉
动态生成java代码???java代码不就是一个后缀名为.java的txt文档吗?仔细想了下,如果要生成这样的代码的确挺麻烦,你要考虑导包的问题,以及复杂的语法
javapoet代码仓库地址
先说几个核心类
- MethodSpec定义方法
- TypeSpec定义类丶接口丶抽象类丶枚举
- JavaFile定义一个输出java文件
MethodSpec介绍
MethodSpec main = MethodSpec.methodBuilder("main")//定义方面名.addModifiers(Modifier.PUBLIC, Modifier.STATIC)//定义修饰符.returns(void.class)//定义返回结果.addParameter(String[].class, "args")//添加方法参数.addStatement("$T.out.println($S)", System.class, "Hello, JavaPoet!")//添加方法内容.build()
TypeSpec介绍
TypeSpec helloWorld = TypeSpec.classBuilder("HelloWorld")//构造一个类,类名.addModifiers(Modifier.PUBLIC, Modifier.FINAL)//定义类的修饰符.addMethod(main)//添加类的方法,也就是上面生成的MethodSpec对象.build();
JavaFile介绍
JavaFile javaFile = JavaFile.builder("com.example.helloworld", helloWorld)//定义生成的包名,和类.build();javaFile.writeTo(System.out);//输出路径,可以收一个file地址
最终生成
package com.example.helloworld;public final class HelloWorld {public static void main(String[] args) {System.out.println("Hello, JavaPoet!");} }
使用小技巧之占位符的使用
- $L,我的理解就是值的使用addStatement("int value=$L", 10)
- $S,字符串,如果被这个用这个占位符占位的会被2个双引号包裹住
- $T,类型,这个很重要,这个会自动导包addStatement("$T obj=new $T()", Persion.class, Persion.class) 生成的就是new Persion(),接收一个class字节码
- $N引用声明.比如你有一个MethodSpec对象,如果你想调用这个方法,下面是一个官方例子
MethodSpec hexDigit = MethodSpec.methodBuilder("hexDigit").addParameter(int.class, "i").returns(char.class).addStatement("return (char) (i < 10 ? i + '0' : i - 10 + 'a')").build();MethodSpec byteToHex = MethodSpec.methodBuilder("byteToHex").addParameter(int.class, "b").returns(String.class).addStatement("char[] result = new char[2]").addStatement("result[0] = $N((b >>> 4) & 0xf)", hexDigit).addStatement("result[1] = $N(b & 0xf)", hexDigit).addStatement("return new String(result)").build();
//生成的代码
public String byteToHex(int b) {char[] result = new char[2];result[0] = hexDigit((b >>> 4) & 0xf);result[1] = hexDigit(b & 0xf);return new String(result); }public char hexDigit(int i) {return (char) (i < 10 ? i + '0' : i - 10 + 'a'); }
使用小技巧之善用循环beginControlFlow和endControlFlow
.beginControlFlow("while(value<$L)", 10)//循环开始
.addStatement("int value2=$L", 10)
.endControlFlow()
while(value<10) {int value2=10;
}
使用小技巧之addCode
MethodSpec main = MethodSpec.methodBuilder("main").addCode(""+ "int total = 0;\n"+ "for (int i = 0; i < 10; i++) {\n"+ " total += i;\n"+ "}\n").build();
使用小技巧之ClassName
ClassName hoverboard = ClassName.get("com.mattel", "Hoverboard");//包名和类名MethodSpec today = MethodSpec.methodBuilder("tomorrow").returns(hoverboard).addStatement("return new $T()", hoverboard).build();
自己写的Demo
public class Demo {public static void main(String args[]) {try {/** * $T 传入一个类型,可以使class或者ClassName对象,这个会自动帮你导入包 * $S 替换一个字符串,会用"引号" * $L 就是占位一个值,一个变量 * $N 就是占位一个方法 可以传入一个MethodSpec对象 */ ClassName persionClassName = ClassName.get("com.awen.demo.bean", "Persion");//这种找到的形式都和class形式一样可以用 MethodSpec main = MethodSpec.methodBuilder("main").addModifiers(Modifier.STATIC, Modifier.PUBLIC).addParameter(String[].class, "args") //添加参数 .addParameter(persionClassName, "myPersion")//添加参数 .returns(persionClassName).addStatement("int value=$L", 10).addStatement("$T obj=new $T()", persionClassName, Persion.class).addStatement("$T.out.println($S)", System.class, "来吧创建一个类来玩玩吧!").beginControlFlow("while(value<$L)", 10)//循环开始 .addStatement("int value2=$L", 10).endControlFlow().addStatement("return new $T()", Class.forName("com.awen.demo.bean.Persion")).build(); //创建变量 FieldSpec fieldSpec = FieldSpec.builder(String.class, "VALUE").addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL).initializer("$S","AAA").build(); TypeSpec classSpec = TypeSpec.classBuilder("Test").addModifiers(Modifier.PUBLIC, Modifier.FINAL).addField(String.class, "name", Modifier.PUBLIC).addField(fieldSpec).addMethod(main) // .addType(classSpec2)//追加一个内部类 .build(); JavaFile build = JavaFile.builder("com.awen.demo", classSpec).build(); build.writeTo(new File("src/main/java")); } catch (Exception e) {System.out.println("发生错误:" + e.getLocalizedMessage()); }} }
生成代码
public final class Test {public static final String VALUE = "AAA"; public String name; public static Persion main(String[] args, Persion myPersion) {int value=10; Persion obj=new Persion(); System.out.println("来吧创建一个类来玩玩吧!"); while(value<10) {int value2=10; }return new Persion(); } }
用处感想
大家其实大家或多或少都其实用过这玩意,只是大家用了别人的罢了,例如ButterKnife,注入框架,为何不用一个注解就不用在写findViewById了?其实无论本质还是要find的,但是为何不需要了呢?就是在编译前期自动帮你生成了部分代码!
还有greendao,其实这个你也发现了,在你build的时候,也会生成一部分代码?怎么生成的呢?所以说这个在插件开发中还是用处很大的,还要继续学习,这个面向的java层代码的生成
我想用这个技术想做的事情
通过定义plugin插件,可以用这个在编译前期生成部分java代码,然后在transform+asm库对class文件进行修改,插入并调用自动生成的java代码,埋点吧!很想学这个玩着个,继续努力
javapoet动态生成java代码相关推荐
- JavaPoet动态生成代码,高薪程序员必会
5 1 2 3 4 5 build.gradle (butterknife-compiler) dependencies { ... compile deps.javapoet ... } 1 2 3 ...
- eclipse编译java项目class文件_动态编译 Java 代码以及生成 Jar 文件
导读: 最近在看 Flink 源码的时候发现到一段实用的代码,该代码实现了 java 动态编译以及生成 jar 文件.将其进行改进后可以应用到我们的平台上,实现在平台页面上编写 java 代码语句,提 ...
- dubbo SPI之@SPI、@Adaptive注解, 以及什么时候动态生成$Adaptive代码
本文基于dubbo2.7.7对如下三个问题分析 @SPI注解的作用 @Adaptive注解的作用,放在Type和Method上的区别和注意点 什么时候动态生成和编译xxx$Adaptive代码 @SP ...
- CXF wsdl2java 生成java代码供客户端使用
CXF wsdl2java 生成java代码供客户端使用 环境配置: 1.下载apache-cxf-2.6.2在环境变量中配置CXF_HOME 值为E:\gavin\cxf\apache-cxf-3. ...
- 【Android APT】注解处理器 ( 根据注解生成 Java 代码 )
文章目录 一.生成 Java 代码 二.实现 IButterKnife 接口 三.视图绑定主要操作 四.完整注解处理器代码 五.博客资源 Android APT 学习进阶路径 : 推荐按照顺序阅读 , ...
- Protobuf生成Java代码(命令行)
1.说明 本文介绍Protobuf生成Java代码的方法, 下载必须的Protobuf工具, 然后通过命令行, 把.proto文件生成Java代码. 2.准备Protobuf工具 2.1.获取prot ...
- Protobuf生成Java代码(Maven)
1.说明 本文介绍Protobuf生成Java代码的方法, 配置对应的Maven插件, 把.proto文件生成Java代码. 2.插件配置 创建Maven工程grpc-compile, 修改pom.x ...
- 通过物理模型生成Java代码
通过物理模型生成Java代码 软件开发过程中,我们一般是先针对数据库建模,物理建模完成后,生成数据库表,编码阶段的时候我们会针对数据库表生成大量的Javaeban或者是实体类 Powertdesign ...
- java插件开发_编写一个IDEA插件之:自动生成Java代码
我很喜欢IDEA的一键自动生成代码功能,例如自动生成构造方法.字段的Get/Set方法.ToString方法等等,除此之外,也有一些插件提供自动生成代码的功能,例如我们所熟悉的GsonFormat插件 ...
最新文章
- Code Sign error: Provisioning profile 'xxxxxxxxxxxxxxxxxxxxxxxxx'
- websocket receive方法内 有循环怎么退出_认识HTML5的WebSocket
- 导数,微积分,牛顿运动学制作创意地图
- Jquery操作Cookie取值错误的解决方法
- python如何爬取网站所有目录_[python] 爬取网站所有的URL
- C#机器学习之判断日报是否合格
- sqlquerystress
- Java 算法 阿尔法乘积
- 如何通过OCJP认证考试
- 除了巨沃、富勒WMS,还有什么更好用的仓库管理系统?
- 基于Android的无线视频监控的设计与实现 -- 开题报告
- 【解决篇】映美FP-530K+打印发票卡纸,色带安装问题
- iptables禁止访问某个域名
- 利用ECharts可视化mysql数据库中的数据
- 如何读取NIFTI格式图像(.nii文件)
- 数据结构 图的邻接表和邻接矩阵实现———c语言
- 收藏,国自然摘要400字符,如何浓缩出精华?(附空白申请模板)
- NTP时间服务器同步时钟系统安装汇总分享
- 一支优秀的兔单克隆抗体是如何研发出来的?
- 怎么把电子版照片换底色?照片换底色最简单的方法