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源码还是非常简单的。