javapoet使用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/starlight_2012/article/details/78614263

javapoet简介

javapoet是一个用于生成.java源文件的Java API。相关的还有javaWriter是javapoet的一个分支,ASM是一个java字节码操纵框架,它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。javapoet常用来做编译时java文件生成,在butterknife和dagger中使用。

javapoet中API的使用

1.我们动态生成类使用TypeSpec.classBuilder()方法,在classBuilder方法中参数类型为String或者ClassName,就是生成class类的名称,ClassName是JavaPoet中定义的一个对象,可以通过ClassName.get()获取,在这个里面可以传入包名和类名组成一个全路径名称,ClassName.get(“www.hikvision.com”,TestBuilder)组成一个www.hikvision.com.TestBuilder全路径名。

     TypeSpec build = TypeSpec.classBuilder("TestBuilder")
            .build();
    String path = Main.class.getResource("/").getPath();
    File file = new File(path);
    JavaFile.builder("www.hikvision.com",build).build().writeTo(file);

#
在上面classBuilder中是类的名称,JavaFile.builder(“www.hikvision.com”,build).build().writeTo(file);”www.hikvision.com”是包名。生成文件如下

    package www.hikvision.com;

    class TestBuilder {
    }

2.可以通过修饰符来修饰一个类,Modifier是修饰符枚举,里面定义了 PUBLIC,PROTECTED,PRIVATE,ABSTRACT,DEFAULT,STATIC,FINAL,
TRANSIENT,VOLATILE,SYNCHRONIZED,NATIVE,STRICTFP;12个修饰符类addModifiers()方法调用

    TypeSpec build = TypeSpec.classBuilder("TestBuilder")
            .addModifiers(Modifier.ABSTRACT,Modifier.PUBLIC,Modifier.STATIC)
            .build();   

3.在生成类中添加字段,通过FieldSpec.builder()来生成字段,在builder定义字段的类型,名称和修饰符,再通过addFiled()添加到类中

          TypeSpec build = TypeSpec.classBuilder("TestBuilder")
            .addModifiers(Modifier.ABSTRACT,Modifier.PUBLIC,Modifier.STATIC)
           .addField(FieldSpec.builder(TypeName.BOOLEAN,"isOpen",Modifier.PROTECTED).build())
           .build();

4.构造方法的添加,通过addMethod()方法添加一个MethodSpec对象,可以通过MethodSpec.constructorBuilder()生成一个构造方法,也可生通过MethodSpec.methodBuilder()成一个普通方法,记得在生成构造方法时通过修饰符addModifiers()修饰构造方法

     TypeSpec build = TypeSpec.classBuilder("TestBuilder")
            .addModifiers(Modifier.ABSTRACT,Modifier.PUBLIC,Modifier.STATIC)

.addMethod(MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC).build())
.build();

5.生成类中使用泛型,使用addTypeVariable方法,可以通过添加TypeVariableName来设置类的泛型
TypeVariableName typeVariableName=TypeVariableName.get(“T”);

         TypeSpec build = TypeSpec.classBuilder("TestBuilder")
            .addModifiers(Modifier.ABSTRACT,Modifier.PUBLIC,Modifier.STATIC)
            .addTypeVariable(typeVariableName)
            .build();

6.泛型约束例如,还是可以通过TypeVariableName来设置

            TypeVariableName typeVariableName=TypeVariableName.get("T",TypeName.get(Main.class));
      TypeSpec build = TypeSpec.classBuilder("TestBuilder")
            .addModifiers(Modifier.ABSTRACT,Modifier.PUBLIC,Modifier.STATIC)
            .addTypeVariable(typeVariableName)
            .build();

7.实现接口通过addSuperinterface()方法实现接口实现

     TypeSpec build = TypeSpec.classBuilder("TestBuilder")
             .addModifiers(Modifier.ABSTRACT,Modifier.PUBLIC,Modifier.STATIC)
             .addSuperinterface(ITest.class)
             .build();

8.继承类superclass()

     TypeSpec build = TypeSpec.classBuilder("TestBuilder")
            .addModifiers(Modifier.ABSTRACT,Modifier.PUBLIC,Modifier.STATIC)
            .superclass(Test.class)
             .build();

9.接口泛型约束 public class A implement B{}这种在接口上面添加泛型约束,通过addSuperinterface()方法和ParameterizedTypeName结合使用,通过ParameterizedTypeName包裹接口类和泛型来实现

            ParameterizedTypeName 
            parameterizedTypeName=ParameterizedTypeName.get(ITest.class,Main.class);
     TypeSpec build = TypeSpec.classBuilder("TestBuilder")
            .addModifiers(Modifier.ABSTRACT,Modifier.PUBLIC,Modifier.STATIC)
            .addSuperinterface(parameterizedTypeName)
            .build();

10.普通方法添加通过addMethod方法,使用MethodSpec.methodBuilder()添加方法

     MethodSpec testMethod = MethodSpec.methodBuilder("test")
            .addModifiers(Modifier.PUBLIC)
            .build();
     TypeSpec build = TypeSpec.classBuilder("TestBuilder")
              .addModifiers(Modifier.ABSTRACT,Modifier.PUBLIC,Modifier.STATIC)
              .addMethod(testMethod)
              .build();

11.返回值添加是MethodSpec.returns()

      MethodSpec testMethod = MethodSpec.methodBuilder("test")
            .addModifiers(Modifier.PUBLIC)
            .returns(Main.class)
            .build();

12.方法参数添加MethodSpec.addParameter

     CodeBlock codeBlock=CodeBlock.builder()
            .add("T temp=t;\n")
            .build();
    MethodSpec testMethod = MethodSpec.methodBuilder("test")
            .addModifiers(Modifier.PUBLIC)
            .addParameter(typeVariableName,"t")
             .build();

13.Map泛型使用

    Map<String, Class<? extends IRouteGroup>>
        ParameterizedTypeName inputMapTypeOfRoot = ParameterizedTypeName.get(
                ClassName.get(Map.class),
                ClassName.get(String.class),
                ParameterizedTypeName.get(
                        ClassName.get(Class.class),
                        WildcardTypeName.subtypeOf(ClassName.get(type_IRouteGroup))
                )
        );

14.代码块$L使用

    private MethodSpec computeRange(String name, int from, int to, String op) {
      return MethodSpec.methodBuilder(name)
          .returns(int.class)
          .addStatement("int result = 0")
          .beginControlFlow("for (int i = $L; i < $L; i++)", from, to)
          .addStatement("result = result $L i", op)
          .endControlFlow()
          .addStatement("return result")
          .build();
    }

代码块添加有两种方法addCode()和addStatement()两种方式,在addCode中可以创建一个CodeBlock代码块添加代码,在生成代码块是可以使用format对代码进行替换,在javapoet中主要用 S , T, L N四种, T S主要替换字符串, L N替换名字,一般调用方法可以通过$N替换。https://github.com/square/javapoet这个是javapoet在github托管网址,有javapoet基础用法,关于泛型使用没有讲解,可以学习butterknife中泛型使用https://github.com/JakeWharton/butterknife,也可以看下我GitHub关于编译时注解demo,https://github.com/starsquare/star_sky里面有相关泛型的引用。

    CodeBlock codeBlock=CodeBlock.builder()
            .add("T temp=t;\n")
            .build();

     MethodSpec testMethod = MethodSpec.methodBuilder("test")
              .addModifiers(Modifier.PUBLIC)
              .addCode(codeBlock)
              .addStatement("$T m=new $T()",Main.class,Main.class)
              .build();

猜你喜欢

转载自blog.csdn.net/starlight_2012/article/details/78614263
今日推荐