Javapoet API(Java代碼自動生成)簡介及使用思路

目錄

基礎總結

JavaPoet簡介

JavaPoet 是一個生成.Java源文件的Java API。源文件生成在annotation processing 或者和一些元數據,例如文件,數據庫設計,協議格式等,進行交互時會很有用。通過代碼生成,你能夠減少冗餘的代碼模板,同時保證唯一正確的源文件爲元數據。

原文
JavaPoet is a Java API for generating .java source files.

Source file generation can be useful when doing things such as annotation processing or interacting with metadata files (e.g., database schemas, protocol formats). By generating code, you eliminate the need to write boilerplate while also keeping a single source of truth for the metadata.

使用總結

基本使用邏輯,按照正常的新建.java,按照邏輯編寫對應的代碼,編寫的代碼替換爲Javapoet的語法就可以了,Javapoet 的語法過一遍不用記憶,甚至看一下最小案例,直接開車都木有問題使用的時候不記得訪問GitHub主頁對應搜索

引用配置

compile 'com.squareup:javapoet:1.11.1'
<dependency>
  <groupId>com.squareup</groupId>
  <artifactId>javapoet</artifactId>
  <version>1.11.1</version>
</dependency>

最小案例

HelloWorld.java

package com.example.helloworld;

public final class HelloWorld {
  public static void main(String[] args) {
    System.out.println("Hello, JavaPoet!");
  }
}

JavaPoet.java

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 helloWorld = TypeSpec.classBuilder("HelloWorld")
    .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
    .addMethod(main)
    .build();

JavaFile javaFile = JavaFile.builder("com.example.helloworld", helloWorld)
    .build();

javaFile.writeTo(System.out);

類說明

  • 類生成:TypeSpec.classBuilder(“HelloWorld”)
  • 接口:TypeSpec.interfaceBuilder(“HelloWorld”)
  • 方法生成:MethodSpec.methodBuilder(“main”)
  • 增加訪問權限: addModifiers(Modifier.PUBLIC, Modifier.STATIC)
  • 屬性:FieldSpec /TypeSpec.addField
  • 參數:ParameterSpec/MethodSpec.addParameter(ParameterSpec)
  • 文檔:MethodSpec.addJavadoc

公共

  • String.format() 字符串格式化
    • $L for Literals .addStatement("result = result $L i", op)
    • $S for Strings .addStatement("return $S", name)
    • $T for Types .addStatement("return new $T()", Date.class) 會自動import java.util.Date;包名
      • 手動指定包名:ClassName hoverboard = ClassName.get("com.mattel", "Hoverboard");
    • Code block 代碼塊
      • CodeBlock.builder().add("I ate $2L $1L", "tacos", 3)
      • map
      Map<String, Object> map = new LinkedHashMap<>();
      map.put("food", "tacos");
      map.put("count", 3);
      CodeBlock.builder().addNamed("I ate $count:L $food:L", map)
      
  • Import static 靜態導入
JavaFile.builder("com.example.helloworld", hello)
    .addStaticImport(hoverboard, "createNimbus")
    .build();

方法相關

  • 增加代碼塊

    • addCode
    MethodSpec main = MethodSpec.methodBuilder("main")
        .addCode(""
            + "int total = 0;\n"
            + "for (int i = 0; i < 10; i++) {\n"
            + "  total += i;\n"
            + "}\n")
        .build();
    
    void main() {
      int total = 0;
      for (int i = 0; i < 10; i++) {
        total += i;
      }
    }
    
    • beginControlFlow( { )ddStatementendControlFlow 不用寫{\n;}
    MethodSpec main = MethodSpec.methodBuilder("main")
        .addStatement("int total = 0")
        .beginControlFlow("for (int i = 0; i < 10; i++)")
        .addStatement("total += i")
        .endControlFlow()
        .build();
    
  • 函數內部調用

public String byteToHex(int b) {
  char[] result = new char[2];
  result[1] = hexDigit(b & 0xf);
  return new String(result);
}
public char hexDigit(int i) {
  return (char) (i < 10 ? i + '0' : i - 10 + 'a');
}
//-------------------------------------
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[1] = $N(b & 0xf)", hexDigit)
    .addStatement("return new String(result)")
    .build();
  • 匿名內部類:Anonymous Inner Classes
  • 抽象方法:Modifier.ABSTRACT
public abstract class HelloWorld {
  protected abstract void flux();
}
//-------------------------
MethodSpec flux = MethodSpec.methodBuilder("flux")
    .addModifiers(Modifier.ABSTRACT, Modifier.PROTECTED)
    .build();
TypeSpec helloWorld = TypeSpec.classBuilder("HelloWorld")
    .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
    .addMethod(flux)
    .build();
  • 構造方法
 public HelloWorld(String greeting) {
    this.greeting = greeting;
  }
//------------------------------
MethodSpec flux = MethodSpec.constructorBuilder()
    .addModifiers(Modifier.PUBLIC)
    .addParameter(String.class, "greeting")
    .addStatement("this.$N = $N", "greeting", "greeting")
    .build();
  • MethodSpec.addAnnotation(Override.class)

其他

  • 參數: Parameters
void welcomeOverlords(final String android, final String robot) {
}
//-------------------------------
ParameterSpec android = ParameterSpec.builder(String.class, "android")
    .addModifiers(Modifier.FINAL)
    .build();
MethodSpec welcomeOverlords = MethodSpec.methodBuilder("welcomeOverlords")
    .addParameter(android)
    .addParameter(String.class, "robot", Modifier.FINAL)
    .build();
  • 屬性:FieldSpec
FieldSpec android = FieldSpec.builder(String.class, "android")
    .addModifiers(Modifier.PRIVATE, Modifier.FINAL)
    .initializer("$S + $L", "Lollipop v.", 5.0d)
    .build();
  • Javadoc

JavaPoet 官網

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章