Java编译器API简介
今天给大家分享的是Java编译器API简介,文章部分内容摘自【优锐课】学习笔记。
Java编译器API
Java编译器API是Java模块(称为java.compiler)的一部分。该模块包括语言模型和注释处理,以及编译器API。它定义了Java编程语言和编译器工具的类型和模型声明,可以在执行期间从应用程序代码中调用它们。注释处理有助于访问注释处理器,可以将其视为Java编译器的插件。它使注释处理器和注释处理工具环境之间能够通信。模型,元素和类型包处理Java编程语言的元素,而util包则帮助处理程序元素和类型。
编译工具
javax.tools包提供了与Java编译器一起使用的接口和类,并且可以在执行期间从程序中调用它。 它提供了一个框架,该框架允许客户端从其自己的应用程序代码定位和运行编译器。它还提供了服务提供者接口(SPI),用于对诊断的结构化访问和用于覆盖文件访问的文件抽象。ToolProvider类提供了编译器API的入口点。此类提供了一些方法来定位编译器的工具提供者。 例如,我们可以轻松地找到系统中安装的编译器支持的Java源版本列表。
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
for(SourceVersion sv:compiler.getSourceVersions()){
System.out.println(sv);
}
输出如下(根据系统中安装的版本)。
RELEASE_3
RELEASE_4
RELEASE_5
RELEASE_6
RELEASE_7
RELEASE_8
RELEASE_9
RELEASE_10
RELEASE_11
在这种情况下,ToolProvider会找到默认的编译器。通过使用服务提供者机制,还可以找到替代的编译器或工具。如果某些供应商提供Java编译器,则jar文件将包含文件META-INF / service / javax.tool.JavaCompiler,并且将包含一行:com.vendor.VendorJavaCompiler。我们可以将jar文件放入类路径中,并按以下方式定位它:
JavaCompiler vendorJavaCompiler =
ServiceLoader.load(JavaCompiler.class).iterator().next();
ServiceProvider是Java的util类之一,用于查找和加载部署在执行环境中的服务提供者。
找到JavaCompiler后,就可以通过Java源代码执行各种编译诊断任务。为了说明这个想法,让我们首先创建一个简单的类,如下所示:
package com.mano.jcapidemo;
import java.util.Random;
public class MyClass {
public static void main(String[] args){
Random r = new Random();
System.out.println("Today your Lucky Number is:
"+r.nextInt(10));
}
}
现在,在创建Java源文件之后,我们可以使用名为DiagnosticCollector的诊断收集器类将诊断收集在列表中。
创建另一个类,从该类中我们将调用编译器来编译上述类MyClass,并将诊断信息报告给该类。换句话说,我们将创建一个应用程序来加载Java源文件,并由Java编译器对其进行编译,并且,如果源代码中有任何错误,请确保将其报告给主机应用程序。
package com.mano.jcapidemo; import com.mano.annotation.CustomAnnotation;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
@SupportedAnnotationTypes("com.mano.annotation.CustomAnnotation")
@SupportedSourceVersion(SourceVersion.RELEASE_10)
public class CustomAnnotationProcessor extends
AbstractProcessor {
public CustomAnnotationProcessor() {
} public Boolean process(Set<? extends
TypeElement> annotations,
RoundEnvironment roundEnv) {
for (Element e : roundEnv.getElementsAnnotatedWith
(CustomAnnotation.class)) {
if (e.getKind() != ElementKind.FIELD) {
processingEnv.getMessager().printMessage(
Diagnostic.Kind.WARNING,
"Not a field", e);
continue;
}
}
return true;
}
}
编译器依赖于两种服务:诊断侦听器和文件管理器。如果提供了侦听器,则将诊断信息提供给侦听器;否则,将向侦听器提供诊断信息。否则,诊断将以未指定的格式格式化,并定向到默认的错误输出系统(System.err)。默认情况下,编译器工具与标准文件管理器关联,并且可以与满足其要求的任何其他文件管理器一起正常工作。
注释处理器
编译过程还包括注释处理器。它执行编译由注释驱动的代码的附加过程。处理过程按一系列轮次进行,其中每个轮次处理其上一轮产生的注释子集。实现注释过程的接口是javax.annotation.processin.Processor。实现类必须提供一个无参数的构造函数,以供工具实例化处理器。处理基础结构应遵循某些协议,例如:
- 通过使用处理器类的无参数构造函数实例化注释处理器。
- 工具通过传递适当的ProcessingEnvironmentinstance实例来调用init方法。
- 这些工具调用由Processor接口定义的方法,例如getSupportedAnnotationTypes(), getSupportedOptions(), 和getSupportedSourceVersion()。这些方法在每次运行中调用一次,而不是在每个回合中调用一次。
- 最后,调用Processor对象上的process ()方法。
例如,简单的注释可以定义如下:
package com.mano.jcapidemo;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
public@interface CustomAnnotation {
}
一个非常简单的注释处理器,用于警告将注释应用于字段以外的任何其他元素,如下所示:
package com.mano.jcapidemo; import com.mano.annotation.CustomAnnotation;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
@SupportedAnnotationTypes("com.mano.annotation.CustomAnnotation")
@SupportedSourceVersion(SourceVersion.RELEASE_10)
public class CustomAnnotationProcessor extends
AbstractProcessor {
public CustomAnnotationProcessor() {
} public Boolean process(Set<? extends
TypeElement> annotations,
RoundEnvironment roundEnv) {
for (Element e : roundEnv.getElementsAnnotatedWith
(CustomAnnotation.class)) {
if (e.getKind() != ElementKind.FIELD) {
processingEnv.getMessager().printMessage(
Diagnostic.Kind.WARNING,
"Not a field", e);
continue;
}
}
return true;
}
}
SupportedAnnotationTypes定义注释处理器将处理哪种类型的注释,SupportedSourceVersion定义其支持的版本。 我们首先扩展AbstractProcessor抽象类,该类允许我们覆盖处理方法。 处理方法内部编写的逻辑完成了所有技巧,这些技巧涉及我们选择设置哪些标准来处理注释。 这最终决定了注释的含义。
元素扫描仪
元素扫描器在编译过程中对所有语言元素执行分析。它根据访问者模式构建,以根据源版本的发布情况,以默认行为扫描程序元素。例如,ElementScanner9根据源版本RELEASE_9和RELEASE_10进行扫描,而ElementScanner8分别根据源版本RELEASE_8进行扫描。这两个类都可以在javax.lang.model.utilpackage中找到。
编译树API Compiler Tree API
有时,有必要将整个Java源文件解析为抽象语法树,尤其是为了进行更深入的分析。Java编译器树API遵守该要求,并与javax.lang.model包紧密关联。它以与元素扫描器相同的模式构建,并且以类似的方式工作。密钥类称为TreePathScanner。它访问所有子树节点,并有助于维护到父节点的路径。要访问特定节点,我们可以简单地覆盖相应的visitorXYZ方法。
总结
Java编译器API从Java应用程序中提供对Java编译器的编程访问。显而易见,此API有更深层的含义,在这里我们只涉及了其中的内容。但是,此快速介绍可能会提供有关在开始使用Java Compiler API时要查找的内容的线索。
参考
Java API文档

Java编译器API简介的更多相关文章
- jxl(Java Excel API) 使用方法 【2】
JAVA EXCEL API简介 Java Excel是一开放源码项目,通过它Java开发人员可以读取Excel文件的内容.创建新的Excel文件.更新已经存在的Excel文件.使用该 API非Win ...
- Java SE 6 新特性: 编译器 API
新 API 功能简介 JDK 6 提供了在运行时调用编译器的 API,后面我们将假设把此 API 应用在 JSP 技术中.在传统的 JSP 技术中,服务器处理 JSP 通常需要进行下面 6 个步骤: ...
- Java Content Repository API 简介 转自(https://www.ibm.com/developerworks/cn/java/j-jcr/)
Java Content Repository API 简介 1 如果曾经试过开发内容管理应用程序,那么您应当非常清楚在实现内容系统时所遇到的固有难题.这个领地有点支离破碎,许多供应商都有自己的私有仓 ...
- Java的脚本机制、编译器API
学习 xxl-job 定时任务时了解到基于 JVM 的 Grovvy 脚本语言.搭建 Jenkins 时知道了编译API 1. Java 脚本机制 Java 的脚本 API 可以让我们调用 JavaS ...
- 构建简单的 C++ 服务组件,第 1 部分: 服务组件体系结构 C++ API 简介
构建简单的 C++ 服务组件,第 1 部分: 服务组件体系结构 C++ API 简介 熟悉将用于 Apache Tuscany SCA for C++ 的 API.您将通过本文了解该 API 的主要组 ...
- Java 2D API - 1. 基本概念
Java 2D API扩展AWT包,对二维图形.文本及成像功能提供了支持,可用于开发复杂的界面.绘图软件和图像编辑器.Java 2D对象位于用户坐标空间(User coordinate space), ...
- ZooKeeper系列4:ZooKeeper API简介及编程
问题导读: 1.ZooKeeper API 共包含几个包? 2.如何使用ZooKeeper API 创建zookeeper应用程序? 1)ZooKeeper API 简介 ZooKeeper AP ...
- Java Servlet 技术简介
Java Servlet 技术简介 Java 开发人员兼培训师 Roy Miller 将我们现有的 servlet 介绍资料修改成了这篇易于学习的实用教程.Roy 将介绍并解释 servlet 是什么 ...
- 【Java】Java Servlet 技术简介
Java 开发人员兼培训师 Roy Miller 将我们现有的 servlet 介绍资料修改成了这篇易于学习的实用教程.Roy 将介绍并解释 servlet 是什么,它们是如何工作的,如何使用它们来创 ...
随机推荐
- suseoj 1212: 推箱子问题(bfs)
1212: 推箱子问题 时间限制: 1 Sec 内存限制: 128 MB提交: 60 解决: 13[提交][状态][讨论版][命题人:liyuansong] 题目描述 码头仓库是划分为n×m个格子 ...
- 力扣(LeetCode)删除排序链表中的重复元素 个人题解
给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次. 这题思路比较简单,同样是快慢针的思路. 用一个整数类型val对应最新的只出现过一次的那个值, 如果节点的下一个节点的值和这个对应则不做别 ...
- Spring Boot2 系列教程(二十六)Spring Boot 整合 Redis
在 Redis 出现之前,我们的缓存框架各种各样,有了 Redis ,缓存方案基本上都统一了,关于 Redis,松哥之前有一个系列教程,尚不了解 Redis 的小伙伴可以参考这个教程: Redis 教 ...
- python:沙盒(virtualenv)
当电脑需要使用多个版本的python时,可以使用沙盒:或者使用docker: virtualenv是Python自带的,通过pip安装的 [root@centos7 public]# cd jinji ...
- linux启动与登录
1.............rescue..............进入维护模式 (grub选项吧这是) 2.linux启动的幕后过程: 1 加电 (再一次联想服务器升级内存时,加电后有个黄色报警,过 ...
- 【阿里巴巴-高德-汽车事业部】【内推】Java技术专家、前端技术专家、C++技术专家(长期招聘)
简历接收邮箱:yx185737@alibaba-inc.com 邮件请备注来自CSDN 一.Java技术专家 职位描述 研究汽车智能化和在线服务前沿技术,从事在线数据服务和车联网服务的设计和研发 负责 ...
- SpringBoot源码学习系列之SpringMVC自动配置
目录 1.ContentNegotiatingViewResolver 2.静态资源 3.自动注册 Converter, GenericConverter, and Formatter beans. ...
- 【前端】 在前端利用数学函数知识+box-shadow解波浪图形
序 今天正在刷数学函数相关题目,刷到了下面这篇文章,哇哦-有意思. 利用cos和sin实现复杂的曲线.传送门在下面. CSS 技巧一则 -- 在 CSS 中使用三角函数绘制曲线图形及展示动画 正巧在复 ...
- java JDK安装包的获取与安装
Java JDK 安装包获取和安装: JDK 1.8.211 官网下载地址 https://www.oracle.com/technetwork/java/javase/downloads/jdk8- ...
- Prometheus 【目录】
正在陆续更新,内容大体包括: rule.标签重置.cAdversior.自动发现(File 自动发现.DNS自动发现.k8s环境自动发现)等... 目录: prometheus[第一篇] Promet ...