JavaPoet的使用指南

前言

对于我来讲,JavaPoet也是不经意间发现的,平常Android开发中:java

主要使用Mvp+RxJava+Dagger2这套框架
复制代码

在这套框架里每次写Activity或者Fragment就会写一套Mvp+Compent+Module,以下图:android

Mvp+Compent+Module每次生成的内容

通过长时间的重复编写,发现这一套Mvp+Compent+Module文件,只有名称是变化的,因此只须要将名称抽象出来,其余只需模板化,就能生成出上述Java文件.编程

正当想怎么可以快捷生成Java文件,这时JavaPoet便出现,并且JavaPoet可以彻底知足需求。bash

本文主要以JavaPoet的使用方法介绍为主,会将JavaPoet的基本API都介绍一遍,你也能够理解成JavaPoet的中文简易教程app

JavaPoet的基本介绍

(1)JavaPoet是一款能够自动生成Java文件的第三方依赖 (2)简洁易懂的API,上手快 (3)让繁杂、重复的Java文件,自动化生成,提升工做效率,简化流程框架

JavaPoet的小试牛刀

为了展现JavaPoet的能力,这里以自动生成一个全新的MainActivity为例。ide

public class MainActivity extends Activity{

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}
复制代码

我在使用JavaPoet的时候,习惯从外向内逐一辈子成,可是这不是标准,这里能够按照本身的方式来理解和生成.ui

public static void main(String[] args) {
        ClassName activity = ClassName.get("android.app", "Activity");

        TypeSpec.Builder mainActivityBuilder = TypeSpec.classBuilder("MainActivity")
                .addModifiers(Modifier.PUBLIC)
                .superclass(activity);

        ClassName override = ClassName.get("java.lang", "Override");

        ClassName bundle = ClassName.get("android.os", "Bundle");

        ClassName nullable = ClassName.get("android.support.annotation", "Nullable");

        ParameterSpec savedInstanceState = ParameterSpec.builder(bundle, "savedInstanceState")
                .addAnnotation(nullable)
                .build();

        MethodSpec onCreate = MethodSpec.methodBuilder("onCreate")
                .addAnnotation(override)
                .addModifiers(Modifier.PROTECTED)
                .addParameter(savedInstanceState)
                .addStatement("super.onCreate(savedInstanceState)")
                .addStatement("setContentView(R.layout.activity_main)")
                .build();

        TypeSpec mainActivity = mainActivityBuilder.addMethod(onCreate)
                .build();

        JavaFile file = JavaFile.builder("com.test", mainActivity).build();

        try {
            file.writeTo(System.out);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
复制代码

MainActivity的生成逻辑图

经过在Main方法中运行以上的代码,就能够直接生成出MainActivity对象,自上而下的观察上述代码,你会发现JavaPoet让java文件变得有逻辑性。编码

JavaPoet的经常使用类

  1. TypeSpec————用于生成类、接口、枚举对象的类
  2. MethodSpec————用于生成方法对象的类
  3. ParameterSpec————用于生成参数对象的类
  4. AnnotationSpec————用于生成注解对象的类
  5. FieldSpec————用于配置生成成员变量的类
  6. ClassName————经过包名和类名生成的对象,在JavaPoet中至关于为其指定Class
  7. ParameterizedTypeName————经过MainClass和IncludeClass生成包含泛型的Class
  8. JavaFile————控制生成的Java文件的输出的类

JavaPoet的经常使用方法

设置修饰关键字

addModifiers(Modifier... modifiers)
复制代码

Modifier是一个枚举对象,枚举值为修饰关键字Public、Protected、Private、Static、Final等等。 全部在JavaPoet建立的对象都必须设置修饰符(包括方法、类、接口、枚举、参数、变量)。spa

设置注解对象

addAnnotation(AnnotationSpec annotationSpec)
addAnnotation(ClassName annotation)
addAnnotation(Class<?> annotation)
复制代码

该方法即为类或方法或参数设置注解,参数便可以是AnnotationSpec,也能够是ClassName,还能够直接传递Class对象。 通常状况下,包含复杂属性的注解通常用AnnotationSpec,若是单纯添加基本注解,无其余附加属性能够直接使用ClassName或者Class便可。

设置注释

addJavadoc(CodeBlock block)
addJavadoc(String format, Object... args)
复制代码

在编写类、方法、成员变量时,能够经过addJavadoc来设置注释,能够直接传入String对象,或者传入CodeBlock(代码块)。

JavaPoet生成类、接口、枚举对象

在JavaPoet中生成类、接口、枚举,必须得经过TypeSpec生成,而classBuilder、interfaceBuilder、enumBuilder即是建立其关键的方法:

建立类:
TypeSpec.classBuilder("类名“) 
TypeSpec.classBuilder(ClassName className)

建立接口:
TypeSpec.interfaceBuilder("接口名称")
TypeSpec.interfaceBuilder(ClassName className)

建立枚举:
TypeSpec.enumBuilder("枚举名称")
TypeSpec.enumBuilder(ClassName className)
复制代码

继承、实现接口

继承类:
.superclass(ClassName className)

实现接口
.addSuperinterface(ClassName className)
复制代码

继承存在泛型的父类

当继承父类存在泛型时,须要使用ParameterizedTypeName

ParameterizedTypeName get(ClassName rawType, TypeName... typeArguments) 复制代码

返回的ParameterizedTypeName对象,已经被添加泛型信息

方法

addMethod(MethodSpec methodSpec)
复制代码

经过配置MethodSpec对象,使用addMethod方法将其添加进TypeSpec中。

枚举

addEnumConstan(String enumValue)
复制代码

经过addEnumConstan方法添加枚举值,参数为枚举值名称。

JavaPoet生成成员变量

JavaPoet生成成员变量是经过FieldSpec的build方法生成.

builder(TypeName type, String name, Modifier... modifiers)
复制代码

只要传入TypeName(Class)、name(名称)、Modifier(修饰符),就能够生成一个基本的成员变量。

成员变量通常来讲由注解(Annotation)、修饰符(Modifier)、Javadoc(注释)、initializer(实例化)。

注解

addAnnotation(TypeName name) 
复制代码

修饰符

addModifiers(Modifier ...modifier)
复制代码

注释

addJavadoc(String format, Object... args)
复制代码

因为上述三个方法,都在通用方法介绍过这里就再也不重复介绍。

实例化

initializer(String format, Object... args)
复制代码

即成员变量的实例化,例:

public Activity mActivity = new Activity;
复制代码

initializer方法中的内容就是“=”后面的内容,下面看下具体的代码实现,上面的成员变量:

ClassName activity = ClassName.get("android.app", "Activity");
  FieldSpec spec = FieldSpec.builder(activity, "mActivity")
                .addModifiers(Modifier.PUBLIC)
                .initializer("new $T", activity)
                .build();
复制代码

JavaPoet生成方法

JavaPoet生成方法分为两种,第一种是构造方法,另外一种为常规的方法。

构造方法

MethodSpec.constructorBuilder()
复制代码

常规方法

MethodSpec.methodBuilder(String name)
复制代码

方法的主要构成有方法参数、注解、返回值、方法体、抛出异常五种,注解能够参考通用方法addAnnotation,其余方法咱们将会一一介绍:

方法参数

addParameter(ParameterSpec parameterSpec)
复制代码

设置方法参数的方法经过addParameterSpec来实现,ParameterSpec的具体使用参考下一小节。

返回值

returns(TypeName returnType)
复制代码

设置方法的返回值,只需传入一个TypeName对象,而TypeName是ClassName,ParameterizedTypeName的基类。

方法体

在JavaPoet中,设置方法体内容有两个方法,分别是addCode和addStatement:

addCode()

addStatement()
复制代码

这两个本质上都是设置方法体内容,可是不一样的是使用addStatement()方法时,你只须要专一于该段代码的内容,至于结尾的分号和换行它都会帮你作好。 而addCode()添加的方法体内容就是一段无格式的代码片,须要开发者本身添加其格式。

方法体模板

在JavaPoet中,设置方法体使用模板是比较常见的,由于addCode和addStatement方法都存在这样的一个重载:

addCode(String format, Object... args)

addStatement(String format, Object... args)
复制代码

在JavaPoet中,format中存在三种特定的占位符:

$T

$T 在JavaPoet代指的是TypeName,该模板主要将Class抽象出来,用传入的TypeName指向的Class来代替。

ClassName bundle = ClassName.get("android.os", "Bundle");
addStatement("$T bundle = new $T()",bundle)
复制代码

上述添加的代码内容为:

Bundle bundle = new Bundle();
复制代码
$N

$N在JavaPoet中代指的是一个名称,例如调用的方法名称,变量名称,这一类存在乎思的名称

addStatement("data.$N()",toString)
复制代码

上述代码添加的内容:

data.toString();
复制代码
$S

$S在JavaPoet中就和String.format中%s同样,字符串的模板,将指定的字符串替换到$S的地方

.addStatement("super.$S(savedInstanceState)","onCreate")
复制代码

即将"onCreate"字符串代替到$S的位置上.

抛出异常

.addException(TypeName name)
复制代码

设置方法抛出异常,可使用addException方法,传入指定的异常的ClassName,便可为该方法设置其抛出该异常.

JavaPoet生成方法参数

JavaPoet生成有参方法时,须要填充参数,而生成参数则须要经过ParameterSpec这个类。

addParameter(ParameterSpec parameterSpec)
复制代码

初始化ParameterSpec

ParameterSpec.builder(TypeName type, String name, Modifier... modifiers)
复制代码

给参数设置其Class,以及参数名称,和修饰符.

一般来讲参数的构成包括:参数的类型(Class)、参数的名称(name)、修饰符(modifiers)、注解(Annotation)

除了builder方法初始化类型、以及名称、修饰符以外,其他能够经过以下方法进行设置:

添加修饰符

.addModifiers(Modifier modifier)
复制代码

添加注解

addAnnotation(TypeName name) 
复制代码

添加修饰符、注解具体使用可参考通用方法。

JavaPoet生成注解

在JavaPoet建立类、成员变量、方法参数、方法,都会用到注解。

若是使用不包含属性的注解能够直接经过

.addAnnotation(TypeName name)
复制代码

直接传入TypeName或者Class进行设置。

若是使用的注解包含属性,而且不止一个时,这时候就须要生成AnnotationSpec来解决,下面简单了解下AnnotationSpec。

初始化AnnotationSpec

AnnotationSpec.builder(ClassName type)
复制代码

能够发现初始化,只需传入ClassName或者Class便可。

设置属性

addMember(String name, String format, Object... args)
复制代码

使用addMember能够设置注解的属性值,name对应的就是属性名称,format的内容即属性体,一样方法体的格式化在这里也是适用的。

JavaPoet如何生成代码

若是上述内容你已经看完,那么恭喜你,你已经明白JavaPoet的意图,可是如今的你,还差最后一步,即如何生成代码。

JavaPoet中负责生成的类是JavaFile

JavaFile.builder(String packageName, TypeSpec typeSpec)
复制代码

JavaFile经过向build方法传入PackageName(Java文件的包名)、TypeSpec(生成的内容)生成。

打印结果

javaFile.writeTo(System.out)
复制代码

生成的内容会输出到控制台中

生成文件

javaFile.writeTo(File file)
复制代码

生成的内容会以java文件的方式,存放到你传入File文件的位置

结束语

当你读完了本文,若是你产生下面的想法:

  1. JavaPoet原来还能够这样
  2. JavaPoet编写过程为何那么流畅,原来Java文件也能够用编程的方式生成
  3. JavaPoet可不能够改进个人编码流程,提高效率

那么说明你已经对JavaPoet感兴趣了,能够本身动手尝试一下,感觉下JavaPoet的魅力。

最后贴一张,JavaPoet秘籍,有了它会很好的帮助你使用JavaPoet.

JavaPoet指导图

(注明:该图来自walfud的我的博客)

上面的博客没法访问,这是掘金的转载

相关文章
相关标签/搜索