JavaPoet 主要是用于java文件的生成

Control Flow

Model 代表类型
TypeSpec classes & interfaces
FieldSpec fields
MethodSpec methods & constructors
ParameterSpec parameters
AnnotationSpec annotations

但是 方法或者构造方法的方法体 是没有被模块化,因为没有 表达类(expression class),声明类(statement class)以及语法树节点(syntax tree node.), 因此方法体中的代码块 使用 String 表示,如下:

  1. MethodSpec main = MethodSpec.methodBuilder("main")
  2. .addCode(""
  3. + "int total = 0;\n"
  4. + "for (int i = 0; i < 10; i++) {\n"
  5. + " total += i;\n"
  6. + "}\n")
  7. .build();

生成如下方法:

void main() {
  int total = 0;
  for (int i = 0; i < 10; i++) {
    total += i;
  }
}

JavaPoet为了简化如上代码中需要关心 分号,换行,缩进等一些繁琐的操作的,提出了 addStatement()简化分号和新的一行,beginControlFlow() + endControlFlow() 简化综括号,分号,和新的一行,缩进等。如下:

MethodSpec main = MethodSpec.methodBuilder("main")
    .addStatement("int total = 0")
    .beginControlFlow("for (int i = 0; i < 10; i++)")
    .addStatement("total += i")
    .endControlFlow()
    .build();

$L for Literals(字面)

用于ControlFlow表达中表示 字面意思 的占位符

private MethodSpec computeRange(String name, int from, int to, String op) {
  return MethodSpec.methodBuilder(name)
      .returns(int.class)
      .addStatement("int result = 0")
      .beginControlFlow("for (int i = $L; i < $L; i++)", from, to)
      .addStatement("result = result $L i", op)
      .endControlFlow()
      .addStatement("return result")
      .build();
}

$S for string

用于ControlFlow表达中表示 String 的占位符,并且自动生成 双引号

private static MethodSpec whatsMyName(String name) {
  return MethodSpec.methodBuilder(name)
      .returns(String.class)
      .addStatement("return $S", name) => reture "name"
      .build();
}

$T for Types

用于ControlFlow表达中表示 类型 的占位符

当引用的类存在时:

MethodSpec today = MethodSpec.methodBuilder("today")
    .returns(Date.class)
    .addStatement("return new $T()", Date.class)
    .build();

生成:
 Date today() {
    return new Date();
  }

当引用的类不存在时:

// 定义不存在的类
ClassName hoverboard = ClassName.get("com.mattel", "Hoverboard");

MethodSpec today = MethodSpec.methodBuilder("tomorrow")
    .returns(hoverboard)
    .addStatement("return new $T()", hoverboard)
    .build();