今天按照《Thinking in Java》中使用apt处理注解一节,将书中代码写了一遍,但运行过程中出现了一个问题让我很纳闷,下面先把代码呈上,问题稍后再说。
程序功能很简单,就是从被注解的类中提取出public方法,然后使用注解处理器生成一个包含这些public方法的接口文件。
具体介绍可以参考原书。
ExtractInterface.java——注解定义
/**
*
*/
package net.lazydoggy.annotations.aptdemo;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author hanzhaozhan
*
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface ExtractInterface {
String value();
}
Multiplier.java——使用了注解的目标类
/**
*
*/
package net.lazydoggy.annotations.aptdemo;
/**
* @author hanzhaozhan
*
*/
@ExtractInterface("Imultiplier")
public class Multiplier {
public int multiply(int x, int y) {
int total = 0;
for (int i = 0; i < x; i++) {
total = add(total, y);
}
return total;
}
private static int add(int x, int y) {
return x + y;
}
public static void main(String[] args) {
Multiplier m = new Multiplier();
System.out.println("11 * 16 = " + m.multiply(11, 16));
}
}
InterfaceExtractorProcessor.java——注解处理器类
package net.lazydoggy.annotations.aptdemo;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import com.sun.mirror.apt.AnnotationProcessor;
import com.sun.mirror.apt.AnnotationProcessorEnvironment;
import com.sun.mirror.declaration.MethodDeclaration;
import com.sun.mirror.declaration.ParameterDeclaration;
import com.sun.mirror.declaration.TypeDeclaration;
public class InterfaceExtractorProcessor implements AnnotationProcessor {
private final AnnotationProcessorEnvironment env;
private ArrayList<MethodDeclaration> interfaceMethods = new ArrayList<MethodDeclaration>();
public InterfaceExtractorProcessor(AnnotationProcessorEnvironment env) {
this.env = env;
}
@Override
public void process() {
for (TypeDeclaration typeDel : env.getSpecifiedTypeDeclarations()) {
ExtractInterface annot = typeDel
.getAnnotation(ExtractInterface.class);
if (annot == null) {
break;
}
for (MethodDeclaration m : typeDel.getMethods()) {
if (m.getModifiers().toString().contains("public")
&& !(m.getModifiers().toString().contains("static"))) {
interfaceMethods.add(m);
}
}
if (interfaceMethods.size() > 0) {
try {
PrintWriter writer = env.getFiler().createSourceFile(
annot.value());
writer.println("package "
+ typeDel.getPackage().getQualifiedName() + ";");
writer.println("public interface " + annot.value() + " {");
for (MethodDeclaration m : interfaceMethods) {
writer.print("\tpublic ");
writer.print(m.getReturnType() + " ");
writer.print(m.getSimpleName() + "(");
int i = 0;
for (ParameterDeclaration param : m.getParameters()) {
writer.print(param.getType() + " "
+ param.getSimpleName());
if (++i < m.getParameters().size()) {
writer.print(",");
}
}
writer.println(");");
}
writer.println("}");
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
InterfaceExtractorProcessorFactory.java——处理器工厂类
/**
*
*/
package net.lazydoggy.annotations.aptdemo;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import com.sun.mirror.apt.AnnotationProcessor;
import com.sun.mirror.apt.AnnotationProcessorEnvironment;
import com.sun.mirror.apt.AnnotationProcessorFactory;
import com.sun.mirror.declaration.AnnotationTypeDeclaration;
/**
* @author hanzhaozhan
*
*/
public class InterfaceExtractorProcessorFactory implements
AnnotationProcessorFactory {
/*
* (non-Javadoc)
*
* @see
* com.sun.mirror.apt.AnnotationProcessorFactory#getProcessorFor(java.util
* .Set, com.sun.mirror.apt.AnnotationProcessorEnvironment)
*/
@Override
public AnnotationProcessor getProcessorFor(
Set<AnnotationTypeDeclaration> atds,
AnnotationProcessorEnvironment env) {
return new InterfaceExtractorProcessor(env);
}
/*
* (non-Javadoc)
*
* @see
* com.sun.mirror.apt.AnnotationProcessorFactory#supportedAnnotationTypes()
*/
@Override
public Collection<String> supportedAnnotationTypes() {
return Collections
.singleton("net.lazydoggy.annotations.aptdemo.ExtractInterface");
}
/*
* (non-Javadoc)
*
* @see com.sun.mirror.apt.AnnotationProcessorFactory#supportedOptions()
*/
@Override
public Collection<String> supportedOptions() {
return Collections.emptySet();
}
}
使用下面命令:
apt -s . -nocompile -factory net.lazydoggy.annotations.aptdemo.InterfaceExtractorProcessorFactory .\net\lazydoggy\annotations\aptdemo\Multiplier.java
就会在当前执行目录下生成一个Imultiplier .java文件,里面定义了我们在处理器中写入的接口。
上面的程序运行时没有问题的,因为其中的一行代码被我改动过,如下:
for (MethodDeclaration m : typeDel.getMethods()) {
if (m.getModifiers().toString().contains("public")
&& !(m.getModifiers().toString().contains("static"))) {
interfaceMethods.add(m);
}
}
书中的代码是这样的:
for (MethodDeclaration m : typeDel.getMethods()) {
if (m.getModifiers().contains(Modifier.PUBLIC)
&& !(m.getModifiers().contains(Modifier.STATIC))) {
interfaceMethods.add(m);
}
}
如果使用书中的代码是无法得到预期结果的,我使用JDK1.6,不知道JDK1.5是否可以。在JDK1.6中,getModifiers()返回Collection<Modifier>类型,而Modifier类中的静态常量(PUBLIC、STATIC等)是int类型,因此书中代码总会返回false。
上面是我的一个方法,应该有更好的方法,希望大家可以分享。
分享到:
相关推荐
APT从原理上讲是一个编译期的注解处理工具(Annotation Processing Tool)。一些主流的三方库(ButterKnife,Glide)都用到了这个技术来生成代码。 Apt有什么好处 自动生成模板代码,提高了开发效率 编译期对注解...
3D边界框注释工具(3D BAT) 安装 克隆存储库: git clone https://github.com/walzimmer/bat-3d.git 安装npm Linux: sudo apt-get install npm Windows: : 安装PHP Storm或WebStorm(带有集成Web服务器的IDE...
创建一些伪类的示例注释处理器。 /annotations -- just annotation class for processor to use /application -- annotated classes used for generation /processor -- annotation processor executed by compile ...
3D边界框注释工具(3D BAT)安装克隆存储库: git clone https://github.com/walzimmer/bat-3d.git 安装npm Linux: sudo apt-get install npm Windows: : 安装PHP Storm或WebStorm(具有集成Web服务器的IDE): :...
您需要安装来绘制注释,并安装aubioonset来查找注释发作: sudo apt-get install aubio-tools 之后,只需运行: python music_transcriber.py music_file_name.wav 例子 单音 输入示例:twinkle_short.wav 带有...
服务器端开发人员基于APT的依赖项注入- 示例模块使用 module org . example { requires io . avaje . inject; // register org.example._DI$BeanScopeFactory from generated sources provides io.avaje.inject.spi ...
它提供了一个灵活的、开箱即用的响应式 UI,可与核心库交互以查看、注释和操作可嵌入任何 Web 项目的 PDF。 该存储库专为有兴趣将 PDFTron WebViewer 集成到 Tomcat JSP Web 应用程序中的任何用户设计。初始设置在...
前匕首一个简单的示例项目,使用 IDE版本2018.1.4 版本4 分行: :显示如何使用 :显示在使用时可能发生的错误 :显示如何解决的问题Gradle设置apt-idea插件我们使用,该插件将注意正确配置注释处理,以便在启动...
学习能力目的用于学习框架的文档Ansible注释Ansible概述1800个模块无代理(与木偶不同) 简单的声明性语言用于编排整个应用程序生命周期你能用Ansible做什么它提供了各种模块,可用于许多自动化任务,例如云,容器,...
注释用法示例 @RestClass(path = "/wsdl") public class TestService { @RestMethod(path = "/helloGest") public static String helloGest() { return "Hello Gest!"; } } 这个怎么运作 以@RestClass注释的类...
2.0.1依赖项和Dagger-Compiler-2.0.1生成的代码添加到我们的build.gradle文件中: compile ' com.google.dagger:dagger:2.0.1 'apt ' com.google.dagger:dagger-compiler:2.0.1 ' 由于Dagger2编译器基于注释,因此...
能够处理 WSGI 的 Web 服务器(显示了 Apache 2 的相关配置示例) # apt-get install libapache2-mod-wsgi 如何在服务器上设置转录环境 更新localsettings.py配置文件(通过复制localsettings.py.example创建此文件...
NLTK书中的注释( ) 原作者:朱莉安娜·纳扎雷(JulianaNazaré)-2013年5月-人工智能课由Khoa Tran修改 这是一个正在进行的工作 ... 在每个目录下都可以找到更多信息(示例代码和注释)。 第4章介绍了基本的P
CruiseYoung提供的带有详细书签的电子书籍目录 ... 深入理解Android:卷I(51CTO网站“2011年度最受读者喜爱的原创IT技术... //这里是源码分析和一些注释。 如有一些需要特别说明的地方,则会用下面的格式表示: ...
sudo apt-get install python -y # Debian install for Python 2.xsudo apt-get install python3 -y # Debian install for Python 3.x正在安装一系列循序渐进的示例告诉您必须运行一个开发环境。 最终,也许我们...
*(缺少时输出,加载顺序(deps),rdeps,这是由于缺少lib / s等导致的,请参见自述文件)$ doil(软件包安装程序) / solver像apt-get + dpkg一样使用gdeptrace,请参阅Source Forge上的doil)dep-trace现在是“ ...
这些工具取决于Eigen模块(主要是Dense)和C ++标准库。 您最好事先安装Eigen3。 对于Linux sudo apt-get install libeigen3-dev 对于Mac brew install eigen 如有必要,可以更改名称空间。 测试 在./test文件夹中...
apt-get install libgsl0-dev 在MATLAB命令行中,您可以混合c文件,例如,通过 mex chol2invchol.c -lgsl -lblas 要在test-functions / robot-pushing /中运行与Box2D相关的代码,请安装。 例子 example_addgp.m是...
与任何好的音频信号处理工具包一样,有单元测试可提供正确性的基本证明。 当前有6个主要的测试用例,它们检查113种不同的条件。 单元测试位于main.cpp ,并使用紧凑的C ++测试框架编写。 先决条件 作为跨平台的构建...