`
米奈希尔
  • 浏览: 268700 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

注解apt工具示例程序

阅读更多

  今天按照《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。

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

 

 

分享到:
评论
4 楼 fondOfJava 2015-05-12  
警告:不带处理器的注释类型: [ExtractInterface]
1 警告
3 楼 tianhandigeng 2013-07-05  
2楼正解
2 楼 610622106 2012-08-14  
@楼主,你弄错了

这原题使用的是:

com.sun.mirror.declaration.Modifier和javax.lang.model.element.Modifier
这两个包下的 Modifier的枚举实例都是字符串

只有java.lang.reflect.Modifier的枚举实例是int类型

而且原 think in java 上这题使用的是 com.sun.mirror.declaration.Modifier


你的代码中,已经导入了如下两个类,就没有导入 Modifier
com.sun.mirror.declaration.ParameterDeclaration; 
com.sun.mirror.declaration.TypeDeclaration;
1 楼 lg_asus 2012-08-10  
thanks very much ~

相关推荐

    Android Apt之Activity Route的示例

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

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

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

    安卓注解的例子,aptdemo。

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

    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的工作原理,以及如何在实际项目中...

    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)技术来生成...

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

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

    使用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开发中广泛用于元数据声明...

    基于外包tomcat的maven实时调试工具

    在IT行业中,开发Java应用程序时,常常需要使用Maven作为构建工具,Tomcat作为应用服务器。然而,Maven与Tomcat的集成调试一直是一个让开发者头疼的问题,因为默认配置下,Maven构建的项目并不支持实时调试和热部署...

    手写注解处理器实现Android控件注入功能

    在Android中,APT就是这样的一个工具,它允许我们在编译时处理注解并自动生成对应的代码。 接下来,我们将分为以下几个步骤来讲解如何实现这个功能: 1. **定义注解(Annotation)**: 首先,我们需要创建一个...

Global site tag (gtag.js) - Google Analytics