Post Views: 13

JavaPoet 是用来生成 Java 代码的一个 Java Library. 学习 JavaPoet, 唯一也是最快的方法是自己动手生成一个 Java Code 文件. 我们用一个非常简单而又全面的例子, 只要你跟着看完, 基本就没有不知道怎么生成的 Java 代码了.

gradle 引用:

compile 'com.squareup:javapoet:1.8.0'

比如, 我们想生成如下的代码, 这段代码基本涵盖了你能遇到的所有用法. 如果哪里不知道怎么生成的, 可以在下面的生成代码里找.

package com.walfud.howtojavapoet;

import java.io.IOException;

import java.io.Serializable;

import java.lang.Comparable;

import java.lang.Exception;

import java.lang.Integer;

import java.lang.Object;

import java.lang.Override;

import java.lang.Runnable;

import java.lang.RuntimeException;

import java.lang.String;

import java.util.HashMap;

import java.util.Map;

public abstract class Clazz extends String implements Serializable, Comparable, Comparable extends String> {

public static final Map mFoo = new HashMap();

static {

}

{

}

@Override

public int method(String string, T t, Map map) throws IOException,

RuntimeException {

int foo = 1;

String bar = "a string";

Object obj = new HashMap(5);

baz(new Runnable(String param) {

@Override

void run() {

}

});

for (int i = 0; i < 5; i++) {

}

while (false) {

}

do {

} while (false);

if (false) {

} else if (false) {

} else {

}

try {

} catch (Exception e) {

e.printStackTrace();

} finally {

}

return 0;

}

class InnerClass {

}

}

JavaPoet 代码:

package com.walfud.howtojavapoet;

import com.squareup.javapoet.*;

import sun.reflect.generics.scope.ClassScope;

import java.io.IOException;

import java.io.Serializable;

import java.lang.annotation.Documented;

import java.lang.reflect.ParameterizedType;

import java.lang.reflect.TypeVariable;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import javax.lang.model.element.Modifier;

/**

* http://android.walfud.com/javapoet-看这一篇就够了/

*/

public class HowToJavaPoetDemo {

public static void main(String[] args) {

TypeSpec clazz = clazz(field(), method(code()));

JavaFile file = JavaFile.builder("com.walfud.howtojavapoet", clazz).build();

System.out.println(file.toString());

}

/**

* `public abstract class Clazz extends String implements Serializable, Comparable, Comparable extends String> {

* ...

* }`

* @param fieldSpec

* @param methodSpec

* @return

*/

public static TypeSpec clazz(FieldSpec fieldSpec, MethodSpec methodSpec) {

return TypeSpec.classBuilder("Clazz")

.addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)

.addTypeVariable(TypeVariableName.get("T"))

.superclass(String.class)

.addSuperinterface(Serializable.class)

.addSuperinterface(ParameterizedTypeName.get(Comparable.class, String.class))

.addSuperinterface(ParameterizedTypeName.get(ClassName.get(Comparable.class), WildcardTypeName.subtypeOf(String.class)))

.addType(TypeSpec.classBuilder("InnerClass").build())

.addStaticBlock(CodeBlock.builder().build())

.addInitializerBlock(CodeBlock.builder().build())

.addField(fieldSpec)

.addMethod(methodSpec)

.build();

}

/**

* `public static final Map mFoo = new HashMap();`

*

* @return

*/

public static FieldSpec field() {

return FieldSpec.builder(ParameterizedTypeName.get(ClassName.get(Map.class), ClassName.get(String.class), TypeVariableName.get("T")), "mFoo", Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)

.initializer("new $T()", HashMap.class)

.build();

}

/**

* `@Override

* public Integer method(String string, T t, Map map) throws IOException, RuntimeException {

* ...

* }`

*

* @param codeBlock

* @return

*/

public static MethodSpec method(CodeBlock codeBlock) {

return MethodSpec.methodBuilder("method")

.addAnnotation(Override.class)

.addTypeVariable(TypeVariableName.get("T"))

.addModifiers(Modifier.PUBLIC)

.returns(int.class)

.addParameter(String.class, "string")

.addParameter(TypeVariableName.get("T"), "t")

.addParameter(ParameterizedTypeName.get(ClassName.get(Map.class), ClassName.get(Integer.class), WildcardTypeName.subtypeOf(TypeVariableName.get("T"))), "map")

.addException(IOException.class)

.addException(RuntimeException.class)

.addCode(codeBlock)

.build();

}

public static CodeBlock code() {

return CodeBlock.builder()

.addStatement("int foo = 1")

.addStatement("$T bar = $S", String.class, "a string")

// Object obj = new HashMap(5);

.addStatement("$T obj = new $T(5)", Object.class, ParameterizedTypeName.get(ClassName.get(HashMap.class), ClassName.get(Integer.class), WildcardTypeName.subtypeOf(TypeVariableName.get("T"))))

// method(new Runnable(String param) {

// @Override

// void run() {

// }

// });

.addStatement("baz($L)", TypeSpec.anonymousClassBuilder("$T param", String.class)

.superclass(Runnable.class)

.addMethod(MethodSpec.methodBuilder("run")

.addAnnotation(Override.class)

.returns(TypeName.VOID)

.build())

.build())

// for

.beginControlFlow("for (int i = 0; i < 5; i++)")

.endControlFlow()

// while

.beginControlFlow("while (false)")

.endControlFlow()

// do... while

.beginControlFlow("do")

.endControlFlow("while (false)")

// if... else if... else...

.beginControlFlow("if (false)")

.nextControlFlow("else if (false)")

.nextControlFlow("else")

.endControlFlow()

// try... catch... finally

.beginControlFlow("try")

.nextControlFlow("catch ($T e)", Exception.class)

.addStatement("e.printStackTrace()")

.nextControlFlow("finally")

.endControlFlow()

.addStatement("return 0")

.build();

}

}

为了方便记忆, 我总结了一张图, 标注了关键或者稍微复杂的那些用法:

$L 是字面量替换, 比如 ("abc$L123", "FOO") => abcFOO123 . 也就是直接替换

$T 是类型替换, 一般用于 ("$T foo", List.class) => List foo . $T 的好处在于 JavaPoet 会自动帮你补全文件开头的  import .

$S 是字符串替换, 比如: ("$S.length()", "foo") => "foo".length() 注意 $S 是将参数替换为了一个带双引号的字符串

$N 是名称替换, 比如你之前定义了一个函数 MethodSpec methodSpec = MethodSpec.methodBuilder("foo").build(); 现在你可以通过 $N 获取这个函数的名称 ("$N", methodSpec) => foo .

注意: 在 Android 工程中, 是无法使用 `javax.lang.model.element.Modifier` 包的, 因为 Android 运行时没有相关的 class. 对于 Android Annotation 的正确姿势(工程结构以及用法), 请参考:Java 注解技术

override java field_JavaPoet 看这一篇就够了相关推荐

  1. Java基础看这一篇就够了

    一.基础知识: 1.JVM.JRE和JDK的区别: JVM(Java Virtual Machine):java虚拟机,用于保证java的跨平台的特性. java语言是跨平台,jvm不是跨平台的. J ...

  2. java面试看这一篇就够了

    由于最近比较忙,项目赶的比较紧所以一直没有更新整理面试题,这次抽了些时间把答应大家的面试题整理出来了感谢各位小伙伴们的支持,你们的支持是我分享的动力,希望在以后的日子里咱们共同学习进步.如果感觉不错就 ...

  3. java注解看这一篇就够了

    java注解-最通俗易懂的讲解 转载 Tanyboye 最后发布于2018-06-05 10:24:36 阅读数 27063 收藏 发布于2018-06-05 10:24:36 分类专栏: java ...

  4. serviceloader java_【java编程】ServiceLoader使用看这一篇就够了

    转载:https://www.jianshu.com/p/7601ba434ff4 想必大家多多少少听过spi,具体的解释我就不多说了.但是它具体是怎么实现的呢?它的原理是什么呢?下面我就围绕这两个问 ...

  5. api网关选型_如何轻松打造百亿流量API网关?看这一篇就够了(下)

    如何轻松打造百亿流量API网关?看这一篇就够了(上) 上篇整体描述了网关的背景,涉及职能.分类.定位环节,本篇进入本文的重点,将会具体谈下百亿级流量API网关的演进过程. 准备好瓜子花生小板凳开始积累 ...

  6. docker 删除所有镜像_关于 Docker 镜像的操作,看完这篇就够啦 !(下)| 文末福利...

    紧接着上篇<关于 Docker 镜像的操作,看完这篇就够啦 !(上)>,奉上下篇 !!! 镜像作为 Docker 三大核心概念中最重要的一个关键词,它有很多操作,是您想学习容器技术不得不掌 ...

  7. mysql ip比较大小_MySQL优化/面试,看这一篇就够了

    原文链接:http://www.zhenganwen.top/articles/2018/12/25/1565048860202.html 作者:Anwen~ 链接:https://www.nowco ...

  8. 基础 | 零散的MySql基础记不住,看这一篇就够啦

    ❝ 这是小小本周的第二篇,本篇将会着重的讲解关于MySql基础的内容,MySql基础看这一篇就够啦. ❞ 送书反馈与继续送书 之情小微信公众号第一次送书,Java深度调试技术,书已经被中奖者麦洛签收, ...

  9. 如何应对大数据分析工程师面试Spark考察,看这一篇就够了

    作者丨斌迪.HappyMint 来源丨大数据与人工智能(ID:ai-big-data) [导读]本篇文章为大家带来spark面试指南,文内会有两种题型,问答题和代码题,题目大部分来自于网络上,有小部分 ...

最新文章

  1. 万字长文的Redis五种数据结构详解(理论+实战),建议收藏。
  2. Castle IOC容器实践之EnterpriseLibrary Configuration Facility
  3. WebApi系列(从.Net 到 .Net Core)【更新】
  4. 美团外卖iOS多端复用的推动、支撑与思考
  5. Ubuntu 16.04 安装第三方Apps Can’t Install Third-Party Apps on Ubuntu 16.04? You’re No
  6. Java学习之面板与布局管理器
  7. 任正非:美国迟早会爱上华为
  8. 11gR2 Grid Infrastructure Installation prerequisites On Windows
  9. .NET Framework 3.5 sp1离线安装方案
  10. oracle数组转换字符串函数,Oracle 字符串转数组的函数
  11. Caffe的简介、依赖、框架
  12. 财经直播搭建干货分享,系统该如何搭建?整套流程及配套细节说明
  13. springboot的测试类
  14. 计算机ppt实训报告总结,计算机实训总结模板
  15. hackRF--初步实战(ubuntu环境)
  16. [分享]一次中移物联网校园招聘javaweb的笔试题
  17. Latex在PPT(beamer格式)中的页脚,插入reference (footnote), 分栏与不分栏两种情况, 以及如何调节footnote的字体大小
  18. 华东师范大学副校长周傲英:未来,中国需要什么样的数据库?
  19. 360浏览器中页面打开如何默认极速模式
  20. 微信在线EXCEL自动统计人数

热门文章

  1. php 常用数组操作
  2. python基础知识和运用
  3. Lintcode: Kth Smallest Number in Sorted Matrix
  4. Atlas Samples Suse Linux 10.1
  5. linux shell awk 中括号 方括号 分割 []
  6. Restful与webService区别
  7. linux libuv 交叉编译 高性能事件驱动库
  8. linux centos 没有service命令 安装方法
  9. c/c++ 避免重复包含 pragma once 和 #ifndef 的区别
  10. linux echo 写二进制文件