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

package annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; /**
* 动物名称注解
*
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AnimalName {
String value() default "";
}

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

2,APT技术

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

1,自定义注解:

@Target({ElementType.TYPE})   ---作用范围 Class

@Retention(RetentionPolicy.CLASS)  ---生命周期:仅保留到.class文件

public @interface Route {
/** Path of route*/
String value(); ---类似于成员变量
}

2,使用方式

@Route(path = "/test/activity2")
public class MainActivity extends AppCompatActivity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test2);
}
}

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

public class RouteProcessor extends AbstractProcessor {

    @Override
public synchronized void init(ProcessingEnvironment env){
// 主要做一些初始化操作
} @Override
public boolean process(Set<? extends TypeElement> annoations, RoundEnvironment env) {
//具体处理注解的逻辑,控制代码的生成
processAnnotations();
} @Override
public Set<String> getSupportedAnnotationTypes() {
// 支持处理的注解类型, 在这里就是@Route } @Override
public SourceVersion getSupportedSourceVersion() {
//java版本 如:jdk1.6or jdk1.7
} }

3,自定义Processor

@AutoService(Processor.class)
public class HelloProcessor extends AbstractProcessor { /** 文件相关的辅助类 用于生成新的源文件、class等 */
private Filer mFiler; @Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
mFiler = processingEnv.getFiler();
} @Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { // 构建方法 此处使用到了square公司的javapoet库,用来辅助生成 类的代码
MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder("show")
.addModifiers(Modifier.PUBLIC);
methodBuilder.addStatement("String test = \"$N\" ","hello annotation world!"); /** 构建类 */
TypeSpec finderClass = TypeSpec.classBuilder("Hello$$Inject")
.addModifiers(Modifier.PUBLIC)
.addMethod(methodBuilder.build())
.build();
try {
JavaFile.builder("com.win.test",finderClass).build().writeTo(mFiler);
} catch (IOException e) {
e.printStackTrace();
}
return true;
} // 支持的注解类型
@Override
public Set<String> getSupportedAnnotationTypes() {
Set<String> types = new LinkedHashSet<>();
types.add(Hello.class.getCanonicalName());
return types;
} @Override
public SourceVersion getSupportedSourceVersion() {
return super.getSupportedSourceVersion();
}
}

在AS工程中使用

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

在项目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. extjs4 treepanel 多个checkbox先中 多个节点选中 多级节点展开

    //<%@ page contentType="text/html; charset=utf-8" %> var checkedNodes = { _data:{}, ...

  2. IE67 下 setattribute class 失效

    解决办法.将class 换成 className ,同理.ff不能识别className,将其换成class element.setAttribute("class"," ...

  3. codeforces 447C. DZY Loves Sequences 解题报告(446A)

    题目链接:http://codeforces.com/problemset/problem/447/C 题目意思:给出 一个 包含 n 个数的序列你,从中需要找出这个序列的最长子串,满足在里面只修改其 ...

  4. LINQ体验(7)——LINQ to SQL语句之Group By/Having和Exists/In/Any/All/Contains

    我们继续讲解LINQ to SQL语句,这篇我们来讨论Group By/Having操作符和Exists/In/Any/All/Contains操作符. Group By/Having操作符 适用场景 ...

  5. hadoop部署之防火墙

    在部署hadoop时,好多资料上都写了要关闭防火墙,如果不关闭可能出现节点间无法通信的情况,于是大家也都这样做了,因此集群通信正常.当然集群一般是处于局域网中的,因此关闭防火墙一般也不会存在安全隐患, ...

  6. 「LuoguP2170」 选学霸(01背包

    Description 老师想从N名学生中选M人当学霸,但有K对人实力相当,如果实力相当的人中,一部分被选上,另一部分没有,同学们就会抗议.所以老师想请你帮他求出他该选多少学霸,才能既不让同学们抗议, ...

  7. 棋盘问题(dp)

    棋盘问题 传送门 题目描述 在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个 ...

  8. 在msys里进行复制和粘贴操作

    You can copy text from an MSYS window to the clipboard simply by selecting the text you want to copy ...

  9. 相对定位relative与绝对定位absolute

    relative:相对定位,并没有脱离原来文档流,依然在原来的位置上,可以通过设置left,top,来设置自己的偏移量,但是它依然占据自己原来的位置,偏移的位置会遮盖其他的元素 absolute:绝对 ...

  10. memset函数学习

    memset是计算机中C/C++语言函数.将s所指向的某一块内存中的后n个 字节的内容全部设置为ch指定的ASCII值, 第一个值为指定的内存地址,块的大小由第三个参数指定,这个函数通常为新申请的内存 ...