刚接触第一感觉

动态生成java代码???java代码不就是一个后缀名为.java的txt文档吗?仔细想了下,如果要生成这样的代码的确挺麻烦,你要考虑导包的问题,以及复杂的语法

javapoet代码仓库地址
其实git地址官方介绍的demo写的很清楚,这里我只是坐下笔记
先说几个核心类
  1. MethodSpec定义方法
  2. TypeSpec定义类丶接口丶抽象类丶枚举
  3. 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
前面说了$T能自动导包,能接受一个Class对象,我们可以用ClassName对象替换class对象
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代码相关推荐

  1. JavaPoet动态生成代码,高薪程序员必会

    5 1 2 3 4 5 build.gradle (butterknife-compiler) dependencies { ... compile deps.javapoet ... } 1 2 3 ...

  2. eclipse编译java项目class文件_动态编译 Java 代码以及生成 Jar 文件

    导读: 最近在看 Flink 源码的时候发现到一段实用的代码,该代码实现了 java 动态编译以及生成 jar 文件.将其进行改进后可以应用到我们的平台上,实现在平台页面上编写 java 代码语句,提 ...

  3. dubbo SPI之@SPI、@Adaptive注解, 以及什么时候动态生成$Adaptive代码

    本文基于dubbo2.7.7对如下三个问题分析 @SPI注解的作用 @Adaptive注解的作用,放在Type和Method上的区别和注意点 什么时候动态生成和编译xxx$Adaptive代码 @SP ...

  4. CXF wsdl2java 生成java代码供客户端使用

    CXF wsdl2java 生成java代码供客户端使用 环境配置: 1.下载apache-cxf-2.6.2在环境变量中配置CXF_HOME 值为E:\gavin\cxf\apache-cxf-3. ...

  5. 【Android APT】注解处理器 ( 根据注解生成 Java 代码 )

    文章目录 一.生成 Java 代码 二.实现 IButterKnife 接口 三.视图绑定主要操作 四.完整注解处理器代码 五.博客资源 Android APT 学习进阶路径 : 推荐按照顺序阅读 , ...

  6. Protobuf生成Java代码(命令行)

    1.说明 本文介绍Protobuf生成Java代码的方法, 下载必须的Protobuf工具, 然后通过命令行, 把.proto文件生成Java代码. 2.准备Protobuf工具 2.1.获取prot ...

  7. Protobuf生成Java代码(Maven)

    1.说明 本文介绍Protobuf生成Java代码的方法, 配置对应的Maven插件, 把.proto文件生成Java代码. 2.插件配置 创建Maven工程grpc-compile, 修改pom.x ...

  8. 通过物理模型生成Java代码

    通过物理模型生成Java代码 软件开发过程中,我们一般是先针对数据库建模,物理建模完成后,生成数据库表,编码阶段的时候我们会针对数据库表生成大量的Javaeban或者是实体类 Powertdesign ...

  9. java插件开发_编写一个IDEA插件之:自动生成Java代码

    我很喜欢IDEA的一键自动生成代码功能,例如自动生成构造方法.字段的Get/Set方法.ToString方法等等,除此之外,也有一些插件提供自动生成代码的功能,例如我们所熟悉的GsonFormat插件 ...

最新文章

  1. Code Sign error: Provisioning profile 'xxxxxxxxxxxxxxxxxxxxxxxxx'
  2. websocket receive方法内 有循环怎么退出_认识HTML5的WebSocket
  3. 导数,微积分,牛顿运动学制作创意地图
  4. Jquery操作Cookie取值错误的解决方法
  5. python如何爬取网站所有目录_[python] 爬取网站所有的URL
  6. C#机器学习之判断日报是否合格
  7. sqlquerystress
  8. Java 算法 阿尔法乘积
  9. 如何通过OCJP认证考试
  10. 除了巨沃、富勒WMS,还有什么更好用的仓库管理系统?
  11. 基于Android的无线视频监控的设计与实现 -- 开题报告
  12. 【解决篇】映美FP-530K+打印发票卡纸,色带安装问题
  13. iptables禁止访问某个域名
  14. 利用ECharts可视化mysql数据库中的数据
  15. 如何读取NIFTI格式图像(.nii文件)
  16. 数据结构 图的邻接表和邻接矩阵实现———c语言
  17. 收藏,国自然摘要400字符,如何浓缩出精华?(附空白申请模板)
  18. NTP时间服务器同步时钟系统安装汇总分享
  19. 一支优秀的兔单克隆抗体是如何研发出来的?
  20. 怎么把电子版照片换底色?照片换底色最简单的方法

热门文章

  1. Python—PEP8规范
  2. git版本回退及代码合并
  3. 将任意窗口固定到桌面最前端
  4. js 清空所有cookie
  5. 椭圆曲线标量乘法快速算法(附源码实现)
  6. Redis:MySQL 算老几?
  7. 什么专业的人适合学嵌入式?
  8. 【初学者】SDK的理解(客户端SDK和服务器端SDK)
  9. oracle透明加密部署及场景使用
  10. WindowsTool