JavaPoet入门

介绍

JavaPoet 是一个用来生成 .java源文件的Java API。

使用

maven依赖

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

创建demo

import javax.lang.model.element.Modifier;

public class Client {

  private static final String PACKAGE = "com.imooc.sourcecode.java.javapoet.test2";

  public static void main(String[] args) {
    testCreateUser();
    testCreateClient();
  }

//创建一个调用实体类的类
  private static void testCreateClient() {
//定义实体类	
    ClassName user = ClassName.get(PACKAGE, "User");
//创建代码块
    CodeBlock mainCodeBlock = CodeBlock
        .builder()
        .addStatement("$T $L = new $T", user, "user", user)
        .addStatement("$T.out.println($L.$L())", System.class, "user", "getUserName")
        .build();
//创建main方法
    MethodSpec mainMethod = MethodSpec
        .methodBuilder("main")
        .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
        .returns(void.class)
        .addParameter(String[].class, "args")
        .addCode(mainCodeBlock)
        .build();
//创建类
    TypeSpec client = TypeSpec.classBuilder("Client")
        .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
        .addMethod(mainMethod)
        .build();

    JavaFile javaFile = JavaFile.builder(PACKAGE, client)
        .build();

    System.out.println(javaFile.toString());
  }


//创建一个带注解的实体类
  private static void testCreateUser() {

//创建一个属性
    FieldSpec userNameField = FieldSpec
        .builder(String.class, "userName") // 定义属性类型和属性名称
        .addModifiers(Modifier.PRIVATE)    // 定义属性修饰符
        .build();
//创建一个无参构造方法
    MethodSpec noArgsContructor = MethodSpec
        .constructorBuilder()
        .addModifiers(Modifier.PUBLIC)  // 定义属性修饰符
        .build();
//创建一个参数
    ParameterSpec userNameParam = ParameterSpec
        .builder(String.class, "userName") // 定义参数类型和参数名称
        .build();
//创建一个有参构造方法
    MethodSpec allArgsContructor = MethodSpec
        .constructorBuilder()
        .addModifiers(Modifier.PUBLIC)
        .addParameter(userNameParam)
        .addStatement("this.$N = $N", userNameParam, userNameParam) // 定义语句
        .build();
//创建一个注解
    AnnotationSpec getterAnnotation = AnnotationSpec
        .builder(Getter.class)
        .build();
//创建一个注解
    AnnotationSpec setterAnnotation = AnnotationSpec
        .builder(Setter.class)
        .build();
//创建一个类
    TypeSpec user = TypeSpec.classBuilder("User")
        .addModifiers(Modifier.PUBLIC, Modifier.FINAL) // 定义类修饰符
        .addField(userNameField)                       // 添加属性
        .addAnnotation(getterAnnotation)               // 添加注解
        .addAnnotation(setterAnnotation)
        .addMethod(noArgsContructor)                   // 添加构造方法
        .addMethod(allArgsContructor)
        .build();

    JavaFile javaFile = JavaFile.builder(PACKAGE, user)
        .build();
//代码生成,转换成字符串
    System.out.println(javaFile.toString());
  }
}

看一下JavaPoet内部是如何处理参数的

private void addArgument(String format, char c, Object arg) {
      switch (c) {
//$N表示获取参数的name
        case 'N':
          this.args.add(argToName(arg));
          break;
//$L表示字面意义,原样输出
        case 'L':
          this.args.add(argToLiteral(arg));
          break;
//$S表示转成字符串
        case 'S':
          this.args.add(argToString(arg));
          break;
//$T表示转成类型,并自动import
        case 'T':
          this.args.add(argToType(arg));
          break;
        default:
          throw new IllegalArgumentException(
              String.format("invalid format string: '%s'", format));
      }
    }
private String argToName(Object o) {
      if (o instanceof CharSequence) return o.toString();
      if (o instanceof ParameterSpec) return ((ParameterSpec) o).name;
      if (o instanceof FieldSpec) return ((FieldSpec) o).name;
      if (o instanceof MethodSpec) return ((MethodSpec) o).name;
      if (o instanceof TypeSpec) return ((TypeSpec) o).name;
      throw new IllegalArgumentException("expected name but was " + o);
    }

创建结果为

package com.imooc.sourcecode.java.javapoet.test2;

import java.lang.String;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public final class User {
  private String userName;

  public User() {
  }

  public User(String userName) {
    this.userName = userName;
  }
}

package com.imooc.sourcecode.java.javapoet.test2;

import java.lang.String;
import java.lang.System;

public final class Client {
  public static void main(String[] args) {
    User user = new User;
    System.out.println(user.getUserName());
  }
}

可以看到使用JavaPoet来生成java源码还是非常简单的。

posted @ 2020-07-12 11:11  strongmore  阅读(1044)  评论(0编辑  收藏  举报