服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - JavaPoet的使用指南小结

JavaPoet的使用指南小结

2021-06-06 14:00Vander丶 Java教程

这篇文章主要介绍了JavaPoet的使用指南小结,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

前言

对于我来说,javapoet也是不经意间发现的,日常android开发中:

主要使用mvp+rxjava+dagger2这套框架

在这套框架里每次写 activity 或者 fragment 就会写一套mvp+compent+module,如下图:

JavaPoet的使用指南小结

生成内容.jpeg

经过长时间的重复编写,发现这一套mvp+compent+module文件,只有名称是变化的,所以只需要将名称抽象出来,其他只需模板化,就能生成出上述java文件.

正当想怎么能够快捷生成java文件,这时javapoet便出现,而且javapoet能够完全满足需求。

本文主要以javapoet的使用方法介绍为主,会将javapoet的基本api都介绍一遍,你也可以理解成javapoet的中文简易教程

javapoet的基本介绍

(1)javapoet是一款可以自动生成java文件的第三方依赖

(2)简洁易懂的api,上手快

(3)让繁杂、重复的java文件,自动化生成,提高工作效率,简化流程

javapoet的小试牛刀

为了展示javapoet的能力,这里以自动生成一个全新的mainactivity为例。

?
1
2
3
4
5
6
7
8
public class mainactivity extends activity{
 
  @override
  protected void oncreate(@nullable bundle savedinstancestate) {
    super.oncreate(savedinstancestate);
    setcontentview(r.layout.activity_main);
  }
}

我在使用javapoet的时候,习惯从外向内逐一生成,但是这不是标准,这里可以按照自己的方式来理解和生成.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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();
    }
  }

通过在main方法中运行以上的代码,就可以直接生成出mainactivity对象,自上而下的观察上述代码,你会发现javapoet让java文件变得有逻辑性。

javapoet的常用类

  •  typespec————用于生成类、接口、枚举对象的类
  • methodspec————用于生成方法对象的类
  • parameterspec————用于生成参数对象的类
  • annotationspec————用于生成注解对象的类
  • fieldspec————用于配置生成成员变量的类
  • classname————通过包名和类名生成的对象,在javapoet中相当于为其指定class
  • parameterizedtypename————通过mainclass和includeclass生成包含泛型的class
  • javafile————控制生成的java文件的输出的类

 javapoet的常用方法

设置修饰关键字

?
1
addmodifiers(modifier... modifiers)

modifier是一个枚举对象,枚举值为修饰关键字public、protected、private、static、final等等。

所有在javapoet创建的对象都必须设置修饰符(包括方法、类、接口、枚举、参数、变量)。

设置注解对象

?
1
2
3
addannotation(annotationspec annotationspec)
addannotation(classname annotation)
addannotation(class<?> annotation)

该方法即为类或方法或参数设置注解,参数即可以是annotationspec,也可以是classname,还可以直接传递class对象。

一般情况下,包含复杂属性的注解一般用annotationspec,如果单纯添加基本注解,无其他附加属性可以直接使用classname或者class即可。

设置注释

?
1
2
addjavadoc(codeblock block)
addjavadoc(string format, object... args)

在编写类、方法、成员变量时,可以通过addjavadoc来设置注释,可以直接传入string对象,或者传入codeblock(代码块)。

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

在javapoet中生成类、接口、枚举,必须得通过typespec生成,而classbuilder、interfacebuilder、enumbuilder便是创建其关键的方法:

?
1
2
3
4
5
6
7
8
9
10
11
创建类:
typespec.classbuilder("类名“)
typespec.classbuilder(classname classname)
 
创建接口:
typespec.interfacebuilder("接口名称")
typespec.interfacebuilder(classname classname)
 
创建枚举:
typespec.enumbuilder("枚举名称")
typespec.enumbuilder(classname classname)

继承、实现接口

?
1
2
3
4
5
继承类:
.superclass(classname classname)
 
实现接口
.addsuperinterface(classname classname)

继承存在泛型的父类

当继承父类存在泛型时,需要使用parameterizedtypename

?
1
parameterizedtypename get(classname rawtype, typename... typearguments)

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

方法

?
1
addmethod(methodspec methodspec)

通过配置methodspec对象,使用addmethod方法将其添加进typespec中。

枚举

?
1
addenumconstan(string enumvalue)

通过addenumconstan方法添加枚举值,参数为枚举值名称。

javapoet生成成员变量

javapoet生成成员变量是通过fieldspec的build方法生成.

?
1
builder(typename type, string name, modifier... modifiers)

只要传入typename(class)、name(名称)、modifier(修饰符),就可以生成一个基本的成员变量。

成员变量一般来说由注解(annotation)、修饰符(modifier)、javadoc(注释)、initializer(实例化)。

注解

?
1
addannotation(typename name)

修饰符

?
1
addmodifiers(modifier ...modifier)

注释

?
1
addjavadoc(string format, object... args)

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

实例化

?
1
initializer(string format, object... args)

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

?
1
public activity mactivity = new activity;

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

?
1
2
3
4
5
classname activity = classname.get("android.app", "activity");
 fieldspec spec = fieldspec.builder(activity, "mactivity")
        .addmodifiers(modifier.public)
        .initializer("new $t", activity)
        .build();

javapoet生成方法

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

构造方法

?
1
methodspec.constructorbuilder()

常规方法

?
1
methodspec.methodbuilder(string name)

方法的主要构成有方法参数、注解、返回值、方法体、抛出异常五种,注解可以参考通用方法addannotation,其他方法我们将会一一介绍:

方法参数

?
1
addparameter(parameterspec parameterspec)

设置方法参数的方法通过addparameterspec来实现,parameterspec的具体使用参考下一小节。

返回值

?
1
returns(typename returntype)

设置方法的返回值,只需传入一个typename对象,而typename是classname,parameterizedtypename的基类。

方法体

在javapoet中,设置方法体内容有两个方法,分别是addcode和addstatement:

?
1
2
addcode()
addstatement()

这两个本质上都是设置方法体内容,但是不同的是使用addstatement()方法时,你只需要专注于该段代码的内容,至于结尾的分号和换行它都会帮你做好。

而addcode()添加的方法体内容就是一段无格式的代码片,需要开发者自己添加其格式。

方法体模板

在javapoet中,设置方法体使用模板是比较常见的,因为addcode和addstatement方法都存在这样的一个重载:

?
1
2
3
addcode(string format, object... args)
 
addstatement(string format, object... args)

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

$t

$t 在javapoet代指的是typename,该模板主要将class抽象出来,用传入的typename指向的class来代替。

?
1
2
classname bundle = classname.get("android.os", "bundle");
addstatement("$t bundle = new $t()",bundle)

上述添加的代码内容为:

?
1
bundle bundle = new bundle();

$n

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

?
1
addstatement("data.$n()",tostring)

上述代码添加的内容:

?
1
data.tostring();

$s

$s在javapoet中就和string.format中%s一样,字符串的模板,将指定的字符串替换到$s的地方

?
1
.addstatement("super.$s(savedinstancestate)","oncreate")

即将"oncreate"字符串代替到$s的位置上.

抛出异常

?
1
.addexception(typename name)

设置方法抛出异常,可以使用addexception方法,传入指定的异常的classname,即可为该方法设置其抛出该异常.

javapoet生成方法参数

javapoet生成有参方法时,需要填充参数,而生成参数则需要通过parameterspec这个类。

?
1
addparameter(parameterspec parameterspec)

初始化parameterspec

?
1
parameterspec.builder(typename type, string name, modifier... modifiers)

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

通常来说参数的构成包括:参数的类型(class)、参数的名称(name)、修饰符(modifiers)、注解(annotation)

除了builder方法初始化类型、以及名称、修饰符之外,其余可以通过如下方法进行设置:

添加修饰符

?
1
.addmodifiers(modifier modifier)

添加注解

?
1
addannotation(typename name)

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

javapoet生成注解

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

如果使用不包含属性的注解可以直接通过

?
1
.addannotation(typename name)

直接传入typename或者class进行设置。

如果使用的注解包含属性,并且不止一个时,这时候就需要生成annotationspec来解决,下面简单了解下annotationspec。

初始化annotationspec

?
1
annotationspec.builder(classname type)

可以发现初始化,只需传入classname或者class即可。

设置属性

?
1
addmember(string name, string format, object... args)

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

javapoet如何生成代码

如果上述内容你已经看完,那么恭喜你,你已经明白javapoet的意图,但是现在的你,还差最后一步,即如何生成代码。

javapoet中负责生成的类是javafile

?
1
javafile.builder(string packagename, typespec typespec)

javafile通过向build方法传入packagename(java文件的包名)、typespec(生成的内容)生成。

打印结果

?
1
javafile.writeto(system.out)

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

生成文件

?
1
javafile.writeto(file file)

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

结束语

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

  • javapoet原来还可以这样
  •  javapoet编写过程为什么那么流畅,原来java文件也可以用编程的方式生成
  • javapoet可不可以改进我的编码流程,提升效率

那么说明你已经对javapoet感兴趣了,可以自己动手尝试一下,感受下javapoet的魅力。

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

JavaPoet的使用指南小结

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://www.jianshu.com/p/3b3bd53ee36a

延伸 · 阅读

精彩推荐