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

  • 相关阅读:
    MFC半透明对话框
    关于.h .lib .dll的总结
    C# 调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配
    LeetCode——011 Container With Most Water
    《Effective C++》——读书笔记
    《More Effective C++》——读书笔记
    Chrome插件推荐
    LeetCode——004-Median-of-Two-Sorted-Arrays
    《STL源码剖析》——第七、八章:仿函数与接配器
    《STL源码剖析》——第五、六:关联容器与算法
  • 原文地址:https://www.cnblogs.com/strongmore/p/13287726.html
Copyright © 2020-2023  润新知