今天按照《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。
上面是我的一个方法,应该有更好的方法,希望大家可以分享。
分享到:
相关推荐
首先,Android Apt是一个编译期的注解处理工具(Annotation Processing Tool),它可以生成模板代码,提高开发效率,并且编译期对注解的处理,相对于运行期对注解的处理,性能上要好的多。Apt可以自动生成模板代码,...
在源代码中,开发者可以使用这个自定义注解来标记类、方法或其他程序元素。 `SourceAnnotationTest2.java`和`SourceAnnotationTest.java`是测试类,它们用于验证注解处理器的功能是否正确。这些测试类通常包含带有...
在Android的注解处理工具(Annotation Processing Tool,APT)的帮助下,我们可以实现如代码生成、编译时检查等多种功能,极大地提高了开发效率和代码质量。下面我们将详细探讨`aptdemo`这个项目,它是一个展示...
**Android中的AOP(面向切面编程)与APT(注解处理工具)** 在Android开发中,AOP(Aspect Oriented Programming,面向切面编程)是一种编程范式,它允许开发者将关注点分离,比如日志记录、权限检查等,从主业务...
【标题】"View注入demo(模仿ButterKnife的APT方式)" 涉及的主要知识点是Android中的编程工具和注解处理技术,特别是APT(Annotation Processing Tool)和ButterKnife库的使用。APT允许开发者在编译时通过注解来生成...
注解不会直接影响程序的执行,但它们能为工具和框架提供重要的指导。本篇文章将深入探讨Java注解的使用及其在实际开发中的应用。 首先,我们了解Java注解的基本结构。一个注解以`@`符号开头,后面跟着注解类型,如`...
在Android开发中,APT(Annotation Processing Tool)是一种在编译时通过注解处理器生成源代码或资源文件的技术。它能够帮助我们实现代码的自动化、减少重复性工作,并提高代码的可维护性和性能。本文将深入探讨...
`APTStudy-main` 是一个可能的学习资源,它可能包含了一个示例项目,演示了如何使用APT来处理自定义注解,以及如何创建和实现注解处理器。通过研究这个项目,你可以更深入地理解APT的工作原理,以及如何在实际项目中...
在编程世界中,Java注解(Annotation)是一个强大的工具,它允许程序员在代码中嵌入元数据,这些元数据不直接影响程序的运行,但可以被编译器或运行时环境用来进行各种处理。Android开发中,注解同样扮演着重要角色...
在Android开发中,APT是Android Annotation Processing Tool的缩写,它是一个基于Java编译器的工具,用于处理编译时注解。APT允许开发者定义自定义注解,并提供处理器来生成额外的源代码或资源文件。这些生成的代码...
标题中的“Node.js-事件总线通过定义事件接口apt方式生成事件代理分发事件给注册并实现的接口类”指的是在Node.js环境中,利用事件驱动模型来构建应用程序,并结合了APT(Annotation Processing Tool)技术来生成...
在Java开发中,注释处理(Annotation Processing)是一种强大的工具,它允许开发者通过元数据(即注解)来生成源代码、编译时检查或其他元编程任务。m2e-apt-poc是一个项目,旨在展示如何在Eclipse环境中利用Maven...
6. **注解处理器**:除了在运行时通过反射获取注解信息,还可以使用Java的注解处理工具(Annotation Processing Tool,APT)在编译期间处理注解。这通常用于生成额外的源代码或编译时检查。 7. **注解的实际应用**:...
在Android中,我们可以使用注解(Annotation)来声明依赖,APT则负责处理这些注解并在编译时生成相应的代码。 在本示例中,`BeauteousJade-blade-a552796`可能是项目或库的名称,其中`blade`可能代表DI框架的主要...
在Android开发领域,APT(Annotation Processing Tool)是一种用于处理注解的工具,它可以在编译时自动生成代码或执行其他构建任务。APT机制是Java语言的一部分,但在Android中也有广泛的应用,尤其在依赖注入、数据...
在IT行业中,"APTDemo案例"通常指的是Android Permission Testing Demo,这是一个用于演示和测试Android应用程序权限管理的示例项目。这个案例深入探讨了Android应用程序如何处理权限请求,以及如何在运行时动态获取...
例如,开发者可以使用注解标记一个类为Presenter,然后通过编译时处理(如使用APT - Annotation Processing Tool)或运行时反射来生成与View和Model交互的代码。 **注解**在Java和Android开发中广泛用于元数据声明...
在IT行业中,开发Java应用程序时,常常需要使用Maven作为构建工具,Tomcat作为应用服务器。然而,Maven与Tomcat的集成调试一直是一个让开发者头疼的问题,因为默认配置下,Maven构建的项目并不支持实时调试和热部署...
在Android中,APT就是这样的一个工具,它允许我们在编译时处理注解并自动生成对应的代码。 接下来,我们将分为以下几个步骤来讲解如何实现这个功能: 1. **定义注解(Annotation)**: 首先,我们需要创建一个...