Jdeparser学习笔记

Jdeparser学习笔记

Jdeparser简介

Jdeparser是JBOSS社区提供的Java源代码生成工具,可以方便生成Java源代码,常用于Annotation Processing中。

Jdeparser常用类

JDeparser

JDeparser类是JDeparser的入口,通过调用createSources函数创建JSources(源码容器)

JSources

JSources是源码容器,通过createSourceFile函数可以创建JSourceFile(源码文件)

JSourceFile

JSourceFile是源码文件,该类包含以下几个函数,用于创建源文件具体内容:

  1. _import 生成iimport语句
  2. importStatic 生成import语句(import类中的静态变量)
  3. blankLine 添加一个空行
  4. _class 生成class
  5. _enum 生成枚举类型
  6. _interface 生成接口
  7. annotationInterface 生成注解接口

_class, _enum, _interface, annotationInterface四个函数会返回JClassDef对象

JClassDef

JClassDef是类定义, 通过该类的一系列函数完成类具体内容定义:

  1. _extends 类继承哪个类
  2. _implements 类实现哪些接口
  3. erasedType 获取当前类擦除类型后的类型
  4. genericType 获取当前
  5. _enum 生成枚举值(该函数不会生成name, 可能是一个bug)
  6. typeParam 生成泛型信息
  7. method 生成方法
  8. annotate 生成类上的注解
  9. field 生成类属性
  10. constructor 生成构造函数
  11. staticInit 生成static静态代码块
  12. init 生成代码块(与staticInit不同, 每次new的时候都会执行init, 看看成构造函数的一部分)

Filer

文件编档员,用于存储JSources, 比如存储JSources到文件, 或者存储到ByteArrayOutputStream中

1 private final JFiler filer = new JFiler() { 2 public OutputStream openStream(final String packageName, final String fileName) throws IOException { 3 final Key key = new Key(packageName, fileName + ".java"); 4 if (!sourceFiles.containsKey(key)) { 5 final ByteArrayOutputStream stream = new ByteArrayOutputStream(); 6 if (sourceFiles.putIfAbsent(key, stream) == null) { 7 return stream; 8 } 9 } 10 throw new IOException("Already exists"); 11 } 12 };

FormatPreferences

生成源文件的格式配置, 比如空格个数等

组件示例

生成一个类

1JSources sources = JDeparser.createSources(getFiler(), new FormatPreferences()); 2JSourceFile bazFile = sources.createSourceFile("org.foo.bar", "Baz");

导入类

1#import java.math.BigDecimal; 2bazFile._import(BigDecimal.class);

生成类

1//@Controller 2//public class Baz<T extends String> extends XXClass implements XXInterface1, XXInterface2{} 3JClassDef classDef = bazFile._class(JMod.PUBLIC, "Baz"); 4classDef.typeParam("T")._extends(String.class); 5classDef._extends("XXClass"); 6classDef._implements("XXInterface1", "XXInterface2"); 7classDef.annotate("Controller");

生成函数声明

1//public String <T extends Thread> foo(T param1, String[] param2, Object... params) throws Exception {} 2public static final int VARARGS = 1 << 31; // JMod.VARARGS不是public的,不能访问 3JMethodDef methodDef = classDef.method(JMod.PUBLIC, String.class, "foo"); 4methodDef.typeParam("T")._extends(Thread.class); 5methodDef.param(JMod.FINAL, "T", "param1"); 6methodDef.param(0 , String[].class.getCanonicalName(), "param2"); 7methodDef.param(JMod.FINAL | VARARGS, Object.class, "params"); 8methodDef._throws(Exception.class);

生成属性

1// private static final String DEFAULT_VALUE = "ONE"; 2classDef.field(JMod.PRIVATE | JMod.STATIC | JMod.FINAL, String.class, "DEFAUL_VALUE", JExprs.str("ONE"));

生成函数体

1JBlock body = methodDef.body(); 2body.xxx

生成if语句

1/** 2if (var1 == null) { 3 var1 = "var1 value"; 4 if (var1.startWith("var1")) { 5 System.out.println(var1); 6 return; 7 } else if (var1.startWith("var1")) { 8 var1 = "var2 value"; 9 return; 10 } 11} 12**/ 13JIf if1 = body._if(JExprs.$v(var1).eq(JExpr.NULL)); 14if1.assign(JExprs.$v(var1), JExprs.str("var1 value")); 15 16JIf if1_1 = if1._if(JExprs.$v(var1).call("startWith").arg(JExprs.str("var1"))); 17if1_1.call(JTypes.$t(System.class).$v("out"), "println").arg(JExprs.$v(var1)); 18if1_1._return(); 19 20JIf if2 = if1.elseIf(JExprs.$v(var1).call("startWith").arg(JExprs.str("var1"))); 21 22JBlock block = if1._else();

注意: if1可以调用elseIf也可以调用_esle, 但是不能两者都调用, 只能调用其中一个, 否则会报错(这里是否有改进的空间)

生成for语句

1//foreach方式 for(String tmp : var1) var1需要可迭代 2body.forEach(0, String.class, "tmp", JExprs.$v(var1)); 3 4//for形式 for (int tmp = 0; tmp <= 10; tmp++) {} 5JFor for1 = body._for(); 6JVarDeclaration testVar = for1.init(0, int.class, "tmp", JExprs.decimal(0)); 7for1.test(JExprs.$v(testVar).le(JExprs.decimal(10))); 8for1.update(JExprs.$v(testVar).postInc());

生成while语句

1//java.sql.ResultSet resultSet = stmt.executeQuery("select * from xx"); 2//while (resultSet.next() == true) {} 3JCall queryCall = JExprs.$v("stmt").call("executeQuery").arg(JExprs.str("select * from xx")); 4JVarDeclaration resultSet = body.var(0, ResultSet.class, "resultSet", queryCall); 5JBlock whileBlock = body._while(JExprs.$v(resultSet).call("next").eq(JExpr.TRUE)); 6 7//do { 8// i++; 9//} while (i<10); 10JBlock doBlock = body._do(JExprs.$v("i<10")); 11doBlock.add(JExprs.$v("i").postInc());

方法调用

1//调用startWith函数, var1.startWith("var1") 2JExprs.$v(var1).call("startWith").arg(JExprs.str("var1"))

生成注释

1classDef.docComment().htmlTag("ul", true).attribute("class", "banana").htmlTag("li", false).text("A line item"); 2classDef.docComment().docTag("author", "Someone"); 3methodDef.blockComment().text("块注释"); 4var1.lineComment().text("行注释").nl();

较为完整的例子

代码如下;

1import org.jboss.jdeparser.*; 2import org.junit.Test; 3 4import java.io.BufferedReader; 5import java.io.ByteArrayInputStream; 6import java.io.IOException; 7import java.io.InputStreamReader; 8import java.math.BigDecimal; 9import java.sql.ResultSet; 10 11public class SimpleExampleTestCase extends AbstractGeneratingTestCase { 12 public static final int VARARGS = 1 << 31; 13 14 15 @Test 16 public void testSimple() throws IOException { 17 18 final JSources sources = JDeparser.createSources(getFiler(), new FormatPreferences()); 19 final JSourceFile bazFile = sources.createSourceFile("org.foo.bar", "Baz"); 20 21 bazFile._import(BigDecimal.class); 22 23 final JClassDef classDef = bazFile._class(JMod.PUBLIC, "Baz"); 24 classDef.docComment().htmlTag("ul", true).attribute("class", "banana").htmlTag("li", false).text("A line item"); 25 classDef.docComment().docTag("author", "Someone"); 26 27 classDef.typeParam("T")._extends(String.class); 28 classDef._extends("XXClass"); 29 classDef._implements("XXInterface1", "XXInterface2"); 30 classDef.annotate("Controller"); 31 32 JVarDeclaration var = classDef.field(JMod.PRIVATE | JMod.STATIC | JMod.FINAL, String.class, "DEFAUL_VALUE", JExprs.str("ONE")); 33 //var.add("ddd", JExpr.NULL); 34 35 JMethodDef methodDef = classDef.method(JMod.PUBLIC, String.class, "foo"); 36 methodDef.blockComment().text("块注释"); 37 ///methodDef.docComment().docTag("Date", "20190101"); 38 39 methodDef.typeParam("T")._extends(String.class); 40 methodDef.param(JMod.FINAL , "T", "param1"); 41 methodDef.param(0 , String[].class.getCanonicalName(), "param2"); 42 methodDef.param(JMod.FINAL | VARARGS, Object.class, "params"); 43 methodDef._throws(Exception.class); 44 45 JBlock body = methodDef.body(); 46 47 JVarDeclaration var1 = body.var(0, String.class, "var1", JExpr.NULL); 48 var1.lineComment().text("行注释").nl(); 49 JIf if1 = body._if(JExprs.$v(var1).eq(JExpr.NULL)); 50 if1.assign(JExprs.$v(var1), JExprs.str("var1 value")); 51 52 JIf if1_1 = if1._if(JExprs.$v(var1).call("startWith").arg(JExprs.str("var1"))); 53 if1_1.call(JTypes.$t(System.class).$v("out"), "println").arg(JExprs.$v(var1)); 54 if1_1._return(); 55 JIf if2 = if1.elseIf(JExprs.$v(var1).call("startWith").arg(JExprs.str("var1"))); 56 if2.assign(JExprs.$v(var1), JExprs.str("var2 value")); 57 if2._return(); 58// JBlock block = if1._else(); 59// block.assign(JExprs.$v(var1), JExprs.str("var3 value")); 60 61 62 body.forEach(0, String.class, "tmp", JExprs.$v(var1)); 63 JFor for1 = body._for(); 64 JVarDeclaration testVar = for1.init(0, int.class, "tmp", JExprs.decimal(0)); 65 for1.test(JExprs.$v(testVar).le(JExprs.decimal(10))); 66 for1.update(JExprs.$v(testVar).postInc()); 67 68 JCall queryCall = JExprs.$v("stmt").call("executeQuery").arg(JExprs.str("select * from xx")); 69 JVarDeclaration resultSet = body.var(0, ResultSet.class, "resultSet", queryCall); 70 JBlock whileBlock = body._while(JExprs.$v(resultSet).call("next").eq(JExpr.TRUE)); 71 72 73 JBlock doBlock = body._do(JExprs.$v("i<10")); 74 doBlock.add(JExprs.$v("i").postInc()); 75 76 sources.writeSources(); 77 final ByteArrayInputStream inputStream = openFile("org.foo.bar", "Baz.java"); 78 final BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); 79 String line; 80 while ((line = reader.readLine()) != null) { 81 System.out.println(line); 82 } 83 } 84} 85

输出结果如下;

1package org.foo.bar; 2 3import java.math.BigDecimal; 4 5/** 6 7 * <ul class="banana"> 8 * <li>A line item 9 * @author Someone 10 11 */ 12@Controller 13public class Baz<T extends String> extends XXClass implements XXInterface1, XXInterface2 { 14 private static final String DEFAUL_VALUE = "ONE"; 15 /* 16 * 块注释 17 */ 18 public <T extends String> String foo(final T param1, String[] param2, final Object... params) throws Exception { 19 // 行注释 20 String var1 = null; 21 if (var1 == null) { 22 var1 = "var1 value"; 23 if (var1.startWith("var1")) { 24 System.out.println(var1); 25 return; 26 } 27 } else if (var1.startWith("var1")) { 28 var1 = "var2 value"; 29 return; 30 } 31 for (String tmp : var1) {} 32 for (int tmp = 0; tmp <= 10; tmp++) {} 33 java.sql.ResultSet resultSet = stmt.executeQuery("select * from xx"); 34 while (resultSet.next() == true) {} 35 do { 36 i++; 37 } while (i<10); 38 } 39}
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

swap空间的增减方法

(1)增大swap空间去激活swap交换区:swapoff v /dev/vg00/lvswap扩展交换lv:lvextend L 10G /dev/vg00/lvswap重新生成swap交换区:mkswap /dev/vg00/lvswap激活新生成的交换区:swapon v /dev/vg00/lvswap