下面是一个简单的自定义注解的栗子:

  1. package annotation;
  2. import java.lang.annotation.Documented;
  3. import java.lang.annotation.ElementType;
  4. import java.lang.annotation.Retention;
  5. import java.lang.annotation.RetentionPolicy;
  6. import java.lang.annotation.Target;
  7. /**
  8. * 动物名称注解
  9. *
  10. */
  11. @Target(ElementType.FIELD)
  12. @Retention(RetentionPolicy.RUNTIME)
  13. @Documented
  14. public @interface AnimalName {
  15. String value() default "";
  16. }

定义了注解,并在需要的时候给相关类,类属性加上注解信息,如果没有响应的注解信息处理流程,注解可以说是没有实用价值,接下来要介绍的是java的APT(Annotation Process Tool)技术,用于处理自定义注解。

2,APT技术

APT(Annotation Process Tool),是一种在代码编译时处理注解,按照一定的规则,生成相应的java文件,多用于对自定义注解的处理,目前比较流行的Dagger2, ButterKnife, EventBus3都是采用APT技术,对运行时的性能影响很小。我们通过自定义注解的方式,来了解一下如何使用APT:

1,自定义注解:

  1. @Target({ElementType.TYPE}) ---作用范围 Class
  2. @Retention(RetentionPolicy.CLASS) ---生命周期:仅保留到.class文件
  3. public @interface Route {
  4. /** Path of route*/
  5. String value(); ---类似于成员变量
  6. }

2,使用方式

  1. @Route(path = "/test/activity2")
  2. public class MainActivity extends AppCompatActivity {
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.activity_test2);
  7. }
  8. }

JVM默认只会处理@override等语言自带的注解,对于自定义的注解,需要我们自己处理,java提供了一个名为AbstractProcessor.java的抽象类,我们只要继承该类,就实现自己的注解处理器,来处理自定义的@Route注解

  1. public class RouteProcessor extends AbstractProcessor {
  2. @Override
  3. public synchronized void init(ProcessingEnvironment env){
  4. // 主要做一些初始化操作
  5. }
  6. @Override
  7. public boolean process(Set<? extends TypeElement> annoations, RoundEnvironment env) {
  8. //具体处理注解的逻辑,控制代码的生成
  9. processAnnotations();
  10. }
  11. @Override
  12. public Set<String> getSupportedAnnotationTypes() {
  13. // 支持处理的注解类型, 在这里就是@Route
  14. }
  15. @Override
  16. public SourceVersion getSupportedSourceVersion() {
  17. //java版本 如:jdk1.6or jdk1.7
  18. }
  19. }

3,自定义Processor

  1. @AutoService(Processor.class)
  2. public class HelloProcessor extends AbstractProcessor {
  3. /** 文件相关的辅助类 用于生成新的源文件、class等 */
  4. private Filer mFiler;
  5. @Override
  6. public synchronized void init(ProcessingEnvironment processingEnv) {
  7. super.init(processingEnv);
  8. mFiler = processingEnv.getFiler();
  9. }
  10. @Override
  11. public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
  12. // 构建方法 此处使用到了square公司的javapoet库,用来辅助生成 类的代码
  13. MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder("show")
  14. .addModifiers(Modifier.PUBLIC);
  15. methodBuilder.addStatement("String test = \"$N\" ","hello annotation world!");
  16. /** 构建类 */
  17. TypeSpec finderClass = TypeSpec.classBuilder("Hello$$Inject")
  18. .addModifiers(Modifier.PUBLIC)
  19. .addMethod(methodBuilder.build())
  20. .build();
  21. try {
  22. JavaFile.builder("com.win.test",finderClass).build().writeTo(mFiler);
  23. } catch (IOException e) {
  24. e.printStackTrace();
  25. }
  26. return true;
  27. }
  28. // 支持的注解类型
  29. @Override
  30. public Set<String> getSupportedAnnotationTypes() {
  31. Set<String> types = new LinkedHashSet<>();
  32. types.add(Hello.class.getCanonicalName());
  33. return types;
  34. }
  35. @Override
  36. public SourceVersion getSupportedSourceVersion() {
  37. return super.getSupportedSourceVersion();
  38. }
  39. }

在AS工程中使用

  1. @Hello("MainTest") //自定义的Hello注解
  2. public class MainActivity extends AppCompatActivity {
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.activity_main);
  7. }
  8. }

在项目App module的build目录下,便会生成对应的java类文件:

这个只是简单的栗子,我们可以在process()方法中,加入更多的业务逻辑,以实现特定功能。

[转]java注解与APT技术的更多相关文章

  1. 秒懂,Java 注解 (Annotation)你可以这样学 - CSDN博客

    https://blog.csdn.net/briblue/article/details/73824058 文章开头先引入一处图片. 这处图片引自老罗的博客.为了避免不必要的麻烦,首先声明我个人比较 ...

  2. 秒懂,Java 注解 (Annotation)你可以这样学

    转自: https://blog.csdn.net/briblue/article/details/73824058 文章开头先引入一处图片. 这处图片引自老罗的博客.为了避免不必要的麻烦,首先声明我 ...

  3. Java 注解 (Annotation)

    Java 注解用于为 Java 代码提供元数据.作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的.Java 注解是从 Java5 开始添加到 Java 的. 注解语法 ...

  4. Java 注解(Annotation)秒懂,你可以这样学,

    文章开头先引入一处图片. 这处图片引自老罗的博客.为了避免不必要的麻烦,首先声明我个人比较尊敬老罗的.至于为什么放这张图,自然是为本篇博文服务,接下来我自会说明.好了,可以开始今天的博文了. Anno ...

  5. (转)秒懂,Java 注解 (Annotation)你可以这样学

    转自:秒懂,Java 注解 (Annotation)你可以这样学 注解如同标签 回到博文开始的地方,之前某新闻客户端的评论有盖楼的习惯,于是 “乔布斯重新定义了手机.罗永浩重新定义了傻X” 就经常极为 ...

  6. Java注解Annotation的用法 - 自定义Annotation实现

    Java注解又称Java标注,是Java语言5.0版本开始支持加入源代码的特殊语法元数据. Java语言中的类.方法.变量.参数和包等都可以被标注.和Javadoc不同,Java标注可以通过反射获取标 ...

  7. (转)秒懂,Java 注解 (Annotation)你可以这样学 ---- 重要 注解定义与反射解析

    转:http://blog.csdn.net/briblue/article/details/73824058 文章开头先引入一处图片.  这处图片引自老罗的博客.为了避免不必要的麻烦,首先声明我个人 ...

  8. attilax.java 注解的本质and 使用最佳实践(3)O7

    attilax.java 注解的本质and 使用最佳实践(3)O7 1. 定义pojo 1 2. 建立注解By eclipse tps 1 3. 注解参数的可支持数据类型: 2 4. 注解处理器 2 ...

  9. Java注解教程及自定义注解

    Java注解提供了关于代码的一些信息,但并不直接作用于它所注解的代码内容.在这个教程当中,我们将学习Java的注解,如何定制注解,注解的使用以及如何通过反射解析注解. Java1.5引入了注解,当前许 ...

随机推荐

  1. MapReduce ChainMapper/ChainReducer

    The ChainMapper class allows to use multiple Mapper classes within a single Map task.  The ChainRedu ...

  2. Delphi通过POST传递参数给PHP

    Delphi代码 ******************************************************************************************* ...

  3. webpack与grunt/glub 的比较

    webpack.grunt.glub 都是前端打包的工具: grunt/gulp 的工作方式是:在一个配置文件中,指明对某些文件进行压缩.组合.检查等任务的具体步骤,然后在运行中输入相应的命令. we ...

  4. caioj1462: 【EXKMP】回文串

    不得不说这是一道好题(前排膜拜灯教授),其实这道题如果不说是EXKMP,很容易就想到Manacher(好像也可以这样做) 回到这道题,这样只有一个字符串,还要求回文?立刻想到了将这个串和它的反串跑EX ...

  5. How to create a List of ValueTuple?

    ValueTuple需要通过NuGet安装System.ValueTuple https://docs.microsoft.com/en-us/dotnet/csharp/tuples?view=ne ...

  6. MYSQL进阶学习笔记五:MySQL函数的创建!(视频序号:进阶_13)

    知识点六:MySQL函数的创建(13) 内置函数: 自定义函数: 首先查看是否已经开启了创建函数的功能: SHOW VARIABLES LIKE ‘%fun%’; 如果变量的值是OFF,那么需要开启 ...

  7. 安装程序工具 (Installutil.exe)

    网址:https://msdn.microsoft.com/zh-cn/library/50614e95(VS.80).aspx  安装程序工具 (Installutil.exe) .NET Fram ...

  8. oracle重命名数据文件

    重命名数据文件   方法1: sql>alter tablespace users offline; sql>host cp /u01/app/oracle/oradata/orcl/us ...

  9. 【扬中集训Day6T1】 白日梦

    [题目描述] 白日梦 (daydream.c/cpp/pas) 时间限制: 1 s  空间限制: 256 MB 题目描述 SR需要相当大的睡眠量 某日,他做了一个奇怪的梦,他梦见自己成为了怪物猎人,为 ...

  10. 数据库sql互转(oracle转mysql为例子)

    转自: https://blog.csdn.net/sinat_32366329/article/details/76402059 在PowerDesinger里找到 File -->> ...