Java代碼產生架構-JavaPoet__Java

來源:互聯網
上載者:User
介紹       JavaPoet是用於產生.Java源檔案的Java API。

         當處理諸如注釋處理或與中繼資料檔案互動(例如,資料庫模式、協議格式)時,源檔案產生可能非常有用。通過產生代碼,您消除了編寫樣板檔案的需要,同時也保留了中繼資料的單一來源。


整合到項目中    

<!-- https://mvnrepository.com/artifact/com.squareup/javapoet -->        <dependency>            <groupId>com.squareup</groupId>            <artifactId>javapoet</artifactId>            <version>1.11.0</version>        </dependency>


代碼產生     類           

        //產生類        TypeSpec helloWorld=TypeSpec.classBuilder("HelloWorld")                .build();        //Java檔案產生        JavaFile javaFile=JavaFile.builder("com.itcast.lyc",helloWorld).build();        try {            //把檔案內容寫入到 視窗列印出來            javaFile.writeTo(System.out);        } catch (IOException e) {            e.printStackTrace();        }

     產生內容如下:

package com.itcast.lyc;class HelloWorld {}

     方法            普通的方法列子
        //產生類構造器        TypeSpec.Builder helloWorldBuilder=TypeSpec.classBuilder("HelloWorld");        MethodSpec main=MethodSpec.methodBuilder("main")//方法的構造器                .addParameter(String[].class,"args")//添加參數                .returns(void.class)//添加傳回值                .addStatement("$T.out.println($S)",System.class,"helloWorld")//新增內容                .addStatement("$T.out.println($L)",System.class,100L)//顯示字元                .build();        TypeSpec helloWorld=helloWorldBuilder.addMethod(main).build();        //Java檔案產生        JavaFile javaFile=JavaFile.builder("com.itcast.lyc",helloWorld).build();        try {            //把檔案內容寫入到 視窗列印出來            javaFile.writeTo(System.out);        } catch (IOException e) {            e.printStackTrace();        }

其中$T代表類的.class類,使用$T和adddStatement匹配能自動匯入包,$S表示注入字串,adddStatement的一種注入字串格式的文法,會自動幫語句添加分號和分行符號,另外還有$L表示數字類型。

產生代碼如下:

package com.itcast.lyc;import java.lang.String;import java.lang.System;class HelloWorld {  void main(String[] args) {    System.out.println("helloWorld");    System.out.println(100);  }}

方法添加代碼的方式還有.addCode("asdasds;\n"),但是.addCode不會自動產生分號和換行,所以也不用,還可以這樣寫.addCode(CodeBlock.builder().addStatement("$S","|sdsad").build())        控制流程     JavaPoet為產生控制流程,給我們提供了便利的API,比如,我們想產生如下內容:

if (true){   System.out.println("ok");}

我們很難想像如果讓我們自己列印{}括弧帶來的麻煩,所以JavaPoet在方法構造器中提供了beginControlFlow和endControlFlow。

  MethodSpec main=MethodSpec.methodBuilder("main")//方法的構造器                .addParameter(String[].class,"args")//添加參數                .returns(void.class)//添加傳回值                .addStatement("$T.out.println($S)",System.class,"helloWorld")//新增內容                .addStatement("$T.out.println($L)",System.class,100L)//顯示字元                .beginControlFlow("if(true)")//控制流程開始                .addStatement("$T.out.println($S)",System.class,"ok")                .endControlFlow()//控制流程結束                .build();
抽象類別
 MethodSpec abstractMethon=MethodSpec.methodBuilder("testAbs")                .addModifiers(Modifier.PUBLIC,Modifier.ABSTRACT)                .build();        TypeSpec typeSpec=TypeSpec.classBuilder("TestAbs")                .addModifiers(Modifier.PUBLIC,Modifier.ABSTRACT)                .addMethod(abstractMethon)                .build();
介面類
   MethodSpec abstractMethon=MethodSpec.methodBuilder("testInterfaces")                .addModifiers(Modifier.PUBLIC,Modifier.ABSTRACT)                .build();        TypeSpec typeSpec=TypeSpec.interfaceBuilder("TestInterfaces")                .addModifiers(Modifier.PUBLIC)                .addField(FieldSpec.builder(String.class,"ONLY_ONCE")                          .addModifiers(Modifier.PUBLIC,Modifier.STATIC,Modifier.FINAL)                          .initializer("$S","OKKK")                          .build())                //添加欄位                .addMethod(abstractMethon)                .build();
 構造方法
      //構造方法        MethodSpec consructorMethod=MethodSpec.constructorBuilder()                .addModifiers(Modifier.PUBLIC)                .addParameter(Integer.class,"age")//參數                .addStatement("this.$N=$N","age","age")//添加樣式代碼$N表示當前類的引用                .build();        TypeSpec helloWorld= helloWorldBuilder                .addMethod(main)//添加main方法                .addField(FieldSpec.builder(Integer.class,"age").addModifiers(Modifier.PRIVATE).build())//添加欄位                .addMethod(consructorMethod)//添加構造方法                .build();
添加參數     
.addParameter(Integer.class,"age")//參數
  
 ParameterizedTypeName parameterizedTypeNameMap=ParameterizedTypeName.get(                ClassName.get(Map.class),                ClassName.get(Integer.class),                ParameterizedTypeName.get(                        ClassName.get(Class.class),                        WildcardTypeName.subtypeOf(ClassName.get(Object.class))                )        );        ParameterizedTypeName parameterizedTypeNameList=ParameterizedTypeName.get(                ClassName.get(List.class),                WildcardTypeName.subtypeOf(ClassName.get(Integer.class))        );        //添加帶參數的方法        MethodSpec parmMethod=MethodSpec.methodBuilder("welomeBeiJing")                .addParameter(String.class,"parm")                .addParameter(ParameterSpec.builder(parameterizedTypeNameMap,"map").build())                .addParameter(ParameterSpec.builder(parameterizedTypeNameList,"list").build())                .build();
最後產生效果:
 void welomeBeiJing(String parm, Map<Integer, Class<?>> map, List<? extends Integer> list) {  }
    需要產生萬用字元的參數 使用 

.addParameter(ParameterSpec.builder(TypeVariableName.get("T"),"t").build())
下面引用別人的圖 加深理解: 點擊開啟連結



添加欄位
 .addField(FieldSpec.builder(Integer.class,"age").addModifiers(Modifier.PRIVATE).build())//添加欄位

Enums
File file=new File(System.getProperty("user.dir"),"\\src\\main\\java");        TypeSpec typeSpec=TypeSpec.enumBuilder("EnumsTest")                .addModifiers(Modifier.PUBLIC)                .addEnumConstant("Rock",TypeSpec.anonymousClassBuilder("$S","Page")                            .addMethod(MethodSpec.methodBuilder("toString")                                    .addAnnotation(Override.class)                                    .addModifiers(Modifier.PUBLIC)                                    .addStatement("return $S","avalanche")                                    .returns(String.class)                                    .build())                        .build())                .addEnumConstant("Sci",TypeSpec.anonymousClassBuilder("$S","ssss").build())                .addEnumConstant("Apple",TypeSpec.anonymousClassBuilder("$S","sad").build())                .addField(String.class,"hand",Modifier.PRIVATE,Modifier.FINAL)                .addMethod(MethodSpec.constructorBuilder()                          .addParameter(String.class,"hand")                          .addStatement("this.$N=$N","hand","hand").build())                .build();        JavaFile javaFile=JavaFile.builder("com.itcast.lyc.javapoet",typeSpec).build();        javaFile.writeTo(file);
  產生代碼:
package com.itcast.lyc.javapoet;import java.lang.Override;import java.lang.String;public enum EnumsTest {  Rock("Page") {    @Override    public String toString() {      return "avalanche";    }  },  Sci("ssss"),  Apple("sad");  private final String hand;  EnumsTest(String hand) {    this.hand=hand;  }}
枚舉類型通過TypeSpec.enumBuilder構造器進行添加枚舉類。

內部類

TypeSpec comparator = TypeSpec.anonymousClassBuilder("")    .addSuperinterface(ParameterizedTypeName.get(Comparator.class, String.class))    .addMethod(MethodSpec.methodBuilder("compare")        .addAnnotation(Override.class)        .addModifiers(Modifier.PUBLIC)        .addParameter(String.class, "a")        .addParameter(String.class, "b")        .returns(int.class)        .addStatement("return $N.length() - $N.length()", "a", "b")        .build())    .build();TypeSpec helloWorld = TypeSpec.classBuilder("HelloWorld")    .addMethod(MethodSpec.methodBuilder("sortByLength")        .addParameter(ParameterizedTypeName.get(List.class, String.class), "strings")        .addStatement("$T.sort($N, $L)", Collections.class, "strings", comparator)        .build())    .build();

得到Java代碼

void sortByLength(List<String> strings) {  Collections.sort(strings, new Comparator<String>() {    @Override    public int compare(String a, String b) {      return a.length() - b.length();    }  });}

內部類構造通過內部類構造方法TypeSpec.anonymousClassBuilder("")初始化內部類,然後使用$L引用對應內部類。


添加註釋

    欄位、方法、類都可以添加註釋

MethodSpec dismiss = MethodSpec.methodBuilder("dismiss")    .addJavadoc("Hides {@code message} from the caller's history. Other\n"        + "participants in the conversation will continue to see the\n"        + "message in their own history unless they also delete it.\n")    .addJavadoc("\n")    .addJavadoc("<p>Use {@link #delete($T)} to delete the entire\n"        + "conversation for all participants.\n", Conversation.class)    .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)    .addParameter(Message.class, "message")    .build();

效果

 /**   * Hides {@code message} from the caller's history. Other   * participants in the conversation will continue to see the   * message in their own history unless they also delete it.   *   * <p>Use {@link #delete(Conversation)} to delete the entire   * conversation for all participants.   */  void dismiss(Message message);

使用$T 引用類。


添加註解

使用AnnotationSpec.builder()添加註解:

MethodSpec logRecord = MethodSpec.methodBuilder("recordEvent")    .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)    .addAnnotation(AnnotationSpec.builder(Headers.class)        .addMember("accept", "$S", "application/json; charset=utf-8")        .addMember("userAgent", "$S", "Square Cash")        .build())    .addParameter(LogRecord.class, "logRecord")    .returns(LogReceipt.class)    .build();

效果

@Headers(    accept = "application/json; charset=utf-8",    userAgent = "Square Cash")LogReceipt recordEvent(LogRecord logRecord);

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.