`
xiangxingchina
  • 浏览: 530283 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

注解apt工具示例程序

 
阅读更多

今天按照《Thinking in Java》中使用apt处理注解一节,将书中代码写了一遍,但运行过程中出现了一个问题让我很纳闷,下面先把代码呈上,问题稍后再说。

  程序功能很简单,就是从被注解的类中提取出public方法,然后使用注解处理器生成一个包含这些public方法的接口文件。

具体介绍可以参考原书。

 

ExtractInterface.java——注解定义

Java代码  收藏代码
  1. /** 
  2.  *  
  3.  */  
  4. package net.lazydoggy.annotations.aptdemo;  
  5.   
  6. import java.lang.annotation.ElementType;  
  7. import java.lang.annotation.Retention;  
  8. import java.lang.annotation.RetentionPolicy;  
  9. import java.lang.annotation.Target;  
  10.   
  11. /** 
  12.  * @author hanzhaozhan 
  13.  * 
  14.  */  
  15. @Target(ElementType.TYPE)  
  16. @Retention(RetentionPolicy.SOURCE)  
  17. public @interface ExtractInterface {  
  18.     String value();  
  19. }  

 

Multiplier.java——使用了注解的目标类

Java代码  收藏代码
  1. /** 
  2.  *  
  3.  */  
  4. package net.lazydoggy.annotations.aptdemo;  
  5.   
  6. /** 
  7.  * @author hanzhaozhan 
  8.  *  
  9.  */  
  10. @ExtractInterface("Imultiplier")  
  11. public class Multiplier {  
  12.     public int multiply(int x, int y) {  
  13.         int total = 0;  
  14.         for (int i = 0; i < x; i++) {  
  15.             total = add(total, y);  
  16.         }  
  17.   
  18.         return total;  
  19.     }  
  20.   
  21.     private static int add(int x, int y) {  
  22.         return x + y;  
  23.     }  
  24.       
  25.     public static void main(String[] args) {  
  26.         Multiplier m = new Multiplier();  
  27.         System.out.println("11 * 16 = " + m.multiply(1116));  
  28.     }  
  29. }  

 

InterfaceExtractorProcessor.java——注解处理器类

Java代码  收藏代码
  1. package net.lazydoggy.annotations.aptdemo;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.PrintWriter;  
  5. import java.util.ArrayList;  
  6.   
  7. import com.sun.mirror.apt.AnnotationProcessor;  
  8. import com.sun.mirror.apt.AnnotationProcessorEnvironment;  
  9. import com.sun.mirror.declaration.MethodDeclaration;  
  10. import com.sun.mirror.declaration.ParameterDeclaration;  
  11. import com.sun.mirror.declaration.TypeDeclaration;  
  12.   
  13. public class InterfaceExtractorProcessor implements AnnotationProcessor {  
  14.     private final AnnotationProcessorEnvironment env;  
  15.     private ArrayList<MethodDeclaration> interfaceMethods = new ArrayList<MethodDeclaration>();  
  16.   
  17.     public InterfaceExtractorProcessor(AnnotationProcessorEnvironment env) {  
  18.         this.env = env;  
  19.     }  
  20.   
  21.     @Override  
  22.     public void process() {  
  23.         for (TypeDeclaration typeDel : env.getSpecifiedTypeDeclarations()) {  
  24.             ExtractInterface annot = typeDel  
  25.                     .getAnnotation(ExtractInterface.class);  
  26.             if (annot == null) {  
  27.                 break;  
  28.             }  
  29.             for (MethodDeclaration m : typeDel.getMethods()) {  
  30.                 if (m.getModifiers().toString().contains("public")  
  31.                         && !(m.getModifiers().toString().contains("static"))) {  
  32.                     interfaceMethods.add(m);  
  33.                 }  
  34.             }  
  35.             if (interfaceMethods.size() > 0) {  
  36.                 try {  
  37.                     PrintWriter writer = env.getFiler().createSourceFile(  
  38.                             annot.value());  
  39.                     writer.println("package "  
  40.                             + typeDel.getPackage().getQualifiedName() + ";");  
  41.                     writer.println("public interface " + annot.value() + " {");  
  42.                     for (MethodDeclaration m : interfaceMethods) {  
  43.                         writer.print("\tpublic ");  
  44.                         writer.print(m.getReturnType() + " ");  
  45.                         writer.print(m.getSimpleName() + "(");  
  46.                         int i = 0;  
  47.                         for (ParameterDeclaration param : m.getParameters()) {  
  48.                             writer.print(param.getType() + " "  
  49.                                     + param.getSimpleName());  
  50.                             if (++i < m.getParameters().size()) {  
  51.                                 writer.print(",");  
  52.                             }  
  53.                         }  
  54.                         writer.println(");");  
  55.                     }  
  56.                     writer.println("}");  
  57.                     writer.close();  
  58.                 } catch (IOException e) {  
  59.                     e.printStackTrace();  
  60.                 }  
  61.   
  62.             }  
  63.         }  
  64.     }  
  65.   
  66. }  

 

InterfaceExtractorProcessorFactory.java——处理器工厂类

Java代码  收藏代码
  1. /** 
  2.  *  
  3.  */  
  4. package net.lazydoggy.annotations.aptdemo;  
  5.   
  6. import java.util.Collection;  
  7. import java.util.Collections;  
  8. import java.util.Set;  
  9.   
  10. import com.sun.mirror.apt.AnnotationProcessor;  
  11. import com.sun.mirror.apt.AnnotationProcessorEnvironment;  
  12. import com.sun.mirror.apt.AnnotationProcessorFactory;  
  13. import com.sun.mirror.declaration.AnnotationTypeDeclaration;  
  14.   
  15. /** 
  16.  * @author hanzhaozhan 
  17.  *  
  18.  */  
  19. public class InterfaceExtractorProcessorFactory implements  
  20.         AnnotationProcessorFactory {  
  21.   
  22.     /* 
  23.      * (non-Javadoc) 
  24.      *  
  25.      * @see 
  26.      * com.sun.mirror.apt.AnnotationProcessorFactory#getProcessorFor(java.util 
  27.      * .Set, com.sun.mirror.apt.AnnotationProcessorEnvironment) 
  28.      */  
  29.     @Override  
  30.     public AnnotationProcessor getProcessorFor(  
  31.             Set<AnnotationTypeDeclaration> atds,  
  32.             AnnotationProcessorEnvironment env) {  
  33.         return new InterfaceExtractorProcessor(env);  
  34.     }  
  35.   
  36.     /* 
  37.      * (non-Javadoc) 
  38.      *  
  39.      * @see 
  40.      * com.sun.mirror.apt.AnnotationProcessorFactory#supportedAnnotationTypes() 
  41.      */  
  42.     @Override  
  43.     public Collection<String> supportedAnnotationTypes() {  
  44.         return Collections  
  45.                 .singleton("net.lazydoggy.annotations.aptdemo.ExtractInterface");  
  46.     }  
  47.   
  48.     /* 
  49.      * (non-Javadoc) 
  50.      *  
  51.      * @see com.sun.mirror.apt.AnnotationProcessorFactory#supportedOptions() 
  52.      */  
  53.     @Override  
  54.     public Collection<String> supportedOptions() {  
  55.         return Collections.emptySet();  
  56.     }  
  57.   
  58. }  

 

使用下面命令:

apt -s . -nocompile -factory net.lazydoggy.annotations.aptdemo.InterfaceExtractorProcessorFactory .\net\lazydoggy\annotations\aptdemo\Multiplier.java

就会在当前执行目录下生成一个Imultiplier .java文件,里面定义了我们在处理器中写入的接口。

 

上面的程序运行时没有问题的,因为其中的一行代码被我改动过,如下:

Java代码  收藏代码
  1. for (MethodDeclaration m : typeDel.getMethods()) {  
  2.     if (m.getModifiers().toString().contains("public")  
  3.             && !(m.getModifiers().toString().contains("static"))) {  
  4.         interfaceMethods.add(m);  
  5.     }  
  6. }  

书中的代码是这样的:

Java代码  收藏代码
  1. for (MethodDeclaration m : typeDel.getMethods()) {  
  2.     if (m.getModifiers().contains(Modifier.PUBLIC)  
  3.             && !(m.getModifiers().contains(Modifier.STATIC))) {  
  4.         interfaceMethods.add(m);  
  5.     }  
  6. }  

 如果使用书中的代码是无法得到预期结果的,我使用JDK1.6,不知道JDK1.5是否可以。在JDK1.6中,getModifiers()返 回Collection<Modifier>类型,而Modifier类中的静态常量(PUBLIC、STATIC等)是int类型,因此书 中代码总会返回false。

上面是我的一个方法,应该有更好的方法,希望大家可以分享。

分享到:
评论

相关推荐

    注解处理器APT(处理方案示例).md

    APT(Annotation Processing Tool,注解处理器工具)是Java编译器提供的一种机制,允许开发者在编译时扫描和处理注解。注解是一种特殊的标记,用于为代码提供元数据信息,APT可以利用这些信息进行特定的代码生成或...

    Android Apt之Activity Route的示例

    首先,Android Apt是一个编译期的注解处理工具(Annotation Processing Tool),它可以生成模板代码,提高开发效率,并且编译期对注解的处理,相对于运行期对注解的处理,性能上要好的多。Apt可以自动生成模板代码,...

    Demo利用APT处理源文件中注解信息

    在源代码中,开发者可以使用这个自定义注解来标记类、方法或其他程序元素。 `SourceAnnotationTest2.java`和`SourceAnnotationTest.java`是测试类,它们用于验证注解处理器的功能是否正确。这些测试类通常包含带有...

    安卓注解的例子,aptdemo。

    在Android的注解处理工具(Annotation Processing Tool,APT)的帮助下,我们可以实现如代码生成、编译时检查等多种功能,极大地提高了开发效率和代码质量。下面我们将详细探讨`aptdemo`这个项目,它是一个展示...

    java.注解处理器APT(解决方案).md

    Java注解处理器APT(Annotation Processing Tool)是Java语言提供的一个工具,用于在编译期间扫描和处理注解。通过使用APT,开发者可以生成额外的源代码、编译器插件或元数据,以实现代码自动生成或自动化处理配置等...

    AOP的apt之android中的实际应用demo

    **Android中的AOP(面向切面编程)与APT(注解处理工具)** 在Android开发中,AOP(Aspect Oriented Programming,面向切面编程)是一种编程范式,它允许开发者将关注点分离,比如日志记录、权限检查等,从主业务...

    View注入demo(模仿ButterKnife的APT方式)

    【标题】"View注入demo(模仿ButterKnife的APT方式)" 涉及的主要知识点是Android中的编程工具和注解处理技术,特别是APT(Annotation Processing Tool)和ButterKnife库的使用。APT允许开发者在编译时通过注解来生成...

    JAVA 注解示例 详解

    注解不会直接影响程序的执行,但它们能为工具和框架提供重要的指导。本篇文章将深入探讨Java注解的使用及其在实际开发中的应用。 首先,我们了解Java注解的基本结构。一个注解以`@`符号开头,后面跟着注解类型,如`...

    Android-AndroidAPT编译时代码生成最佳实践

    在Android开发中,APT(Annotation Processing Tool)是一种在编译时通过注解处理器生成源代码或资源文件的技术。它能够帮助我们实现代码的自动化、减少重复性工作,并提高代码的可维护性和性能。本文将深入探讨...

    APTStudy:APTStudy APT英文全称:Android注解处理工具是一种处理注解的工具,它对源代码文件进行检测发现其中的注解,使用注解进行额外的处理。注解在处理时可以根据源文件中的Annotation生成额外的源文件和其他文件(文件具体内容由Annotation处理器的编写者决定),APT随后编译生成源文件和原来的源文件,将它们一起生成类文件。简言之:APT可以把注解,在编译时生成代码

    `APTStudy-main` 是一个可能的学习资源,它可能包含了一个示例项目,演示了如何使用APT来处理自定义注解,以及如何创建和实现注解处理器。通过研究这个项目,你可以更深入地理解APT的工作原理,以及如何在实际项目中...

    m2e-apt-poc:使用与 Eclipse 集成的 Maven 进行注释处理的概念证明

    在Java开发中,注释处理(Annotation Processing)是一种强大的工具,它允许开发者通过元数据(即注解)来生成源代码、编译时检查或其他元编程任务。m2e-apt-poc是一个项目,旨在展示如何在Eclipse环境中利用Maven...

    android&java的注解详解demo

    在编程世界中,Java注解(Annotation)是一个强大的工具,它允许程序员在代码中嵌入元数据,这些元数据不直接影响程序的运行,但可以被编译器或运行时环境用来进行各种处理。Android开发中,注解同样扮演着重要角色...

    APT-Source-Code:知乎专栏-编译时注解的源代码-源码时代

    在Android开发中,APT是Android Annotation Processing Tool的缩写,它是一个基于Java编译器的工具,用于处理编译时注解。APT允许开发者定义自定义注解,并提供处理器来生成额外的源代码或资源文件。这些生成的代码...

    Node.js-事件总线通过定义事件接口apt方式生成事件代理分发事件给注册并实现的接口类

    标题中的“Node.js-事件总线通过定义事件接口apt方式生成事件代理分发事件给注册并实现的接口类”指的是在Node.js环境中,利用事件驱动模型来构建应用程序,并结合了APT(Annotation Processing Tool)技术来生成...

    使用annotation获取实体类注释

    6. **注解处理器**:除了在运行时通过反射获取注解信息,还可以使用Java的注解处理工具(Annotation Processing Tool,APT)在编译期间处理注解。这通常用于生成额外的源代码或编译时检查。 7. **注解的实际应用**:...

    Android-使用APT实现的一个DI框架

    在Android中,我们可以使用注解(Annotation)来声明依赖,APT则负责处理这些注解并在编译时生成相应的代码。 在本示例中,`BeauteousJade-blade-a552796`可能是项目或库的名称,其中`blade`可能代表DI框架的主要...

    APT使用Demo

    在Android开发领域,APT(Annotation Processing Tool)是一种用于处理注解的工具,它可以在编译时自动生成代码或执行其他构建任务。APT机制是Java语言的一部分,但在Android中也有广泛的应用,尤其在依赖注入、数据...

    APTDemo案例

    在IT行业中,"APTDemo案例"通常指的是Android Permission Testing Demo,这是一个用于演示和测试Android应用程序权限管理的示例项目。这个案例深入探讨了Android应用程序如何处理权限请求,以及如何在运行时动态获取...

    注解mvp框架

    例如,开发者可以使用注解标记一个类为Presenter,然后通过编译时处理(如使用APT - Annotation Processing Tool)或运行时反射来生成与View和Model交互的代码。 **注解**在Java和Android开发中广泛用于元数据声明...

Global site tag (gtag.js) - Google Analytics