概述
注解(Annotation):是元数据的一种形式,能够添加到Java源代码,Java中的类、方法、变量、参数、包都可以被注解。注解对他们所注解的代码没有直接的影响。
注解的使用可以简化代码,提高开发效率。
在Android中,用到注解的开源库有:Retrofit、ButterKnife、Dagger。
Annotation分类
标准Annotation
标准Annotation是指Java自带的几个Annotation:
@Override、@Deprecated、@SuppressWarnings
元Annotation
元Annotation是指用来定义Annotation的Annotation:
@Documented:保存到Javadoc文档中。
@Retention:保留时间,可选值SOURCE(源码)、CLASS(编译时)、RUNTIME(运行时);默认为CLASS,SOURCE大都为Mark Annotation,这类Annotation大都用来校验,如Override。
@Target:表示该注解可以修饰那些程序元素,值为:TYPE、METHOD、CONSTRUCTOR、FIELD、PARAMETER等,未标记则表示可修饰所有。
@Inherited:是否可以被继承,默认为false。
自定义Annotation
根据自己需要进行自定义的Annotation,定义时需要用到上面的元Annotation。
Annotation自定义
定义
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 
 | @Documented@Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.METHOD)
 @Inherited
 public @interface Request {
 
 String GET = "get";
 String POST = "post";
 
 String host();
 
 String path();
 
 int version() default 1;
 
 String method();
 }
 
 | 
语法说明:
- 通过- @interface定义,注解类名即为注解名;
 
- 注解配置参数为注解类的方法名: - (1)所有的方法没有方法体,没有参数,没有修饰符,不允许抛出异常; - (2)方法的返回值只能是基本类型、String、Class、enum、Annotation、及他们的一维数组; - (3)若只有一个默认属性,可直接用- value()函数;
 - (4)若一个属性都没有的表示该Annotation为标记注解(Mark Annotation)如@Override; - (5)可以加- default表示默认值。
 
调用
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 
 | public class HttpUtil {
 @Request(host = "https://api.github.com/", path = "users", method = Request.GET)
 public void request1() {
 
 }
 
 @Request(host = "https://api.github.com/", path = "users/xch168/repos", method = Request.POST, version = 2)
 public void request2() {
 
 }
 }
 
 | 
Annotation解析
运行时Annotation解析
(1)运行时Annotation指@Retention为RUNTIME的Annotation。
(2)常用API
| 12
 3
 4
 5
 6
 
 | method.getAnnotation(AnnotationName.class);
 
 method.getAnnotations();
 
 method.isAnnotationPresent(AnnotationName.class);
 
 | 
(3)解析示例:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 
 | public static void main(String[] args) {try {
 Class clz = Class.forName("com.github.xch168.annotationdemo.HttpUtil");
 for (Method method : clz.getMethods()) {
 if (method.isAnnotationPresent(Request.class)) {
 Request request = method.getAnnotation(Request.class);
 
 System.out.println("method name:" + method.getName());
 System.out.println("request host:" + request.host());
 System.out.println("request path:" + request.path());
 System.out.println("request method:" + request.method());
 System.out.println("request version:" + request.version());
 System.out.println("-----------------");
 }
 }
 } catch (ClassNotFoundException e) {
 e.printStackTrace();
 }
 }
 
 | 
运行结果:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 
 | method name:request1request host:https:
 request path:users
 request method:get
 request version:1
 -----------------
 method name:request2
 request host:https:
 request path:users/xch168/repos
 request method:post
 request version:2
 -----------------
 
 | 
编译时Annotation解析
(1)编译时Annotation指@Retention为CLASS的Annotation,由编译器自动解析。
(2)自定义类继承自AbstractProcessor,并重写其中的process函数。
  示例代码:将上面的Request的@Retention改为CLASS:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 
 | @SupportedAnnotationTypes({"com.github.xch168.annotationdemo.Request"})
 public class RequestProcessor extends AbstractProcessor {
 
 
 
 
 
 
 
 @Override
 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment env) {
 HashMap<String, String> map = new HashMap<>();
 for (TypeElement te : annotations) {
 for (Element element : env.getElementsAnnotatedWith(te)) {
 Request request = element.getAnnotation(Request.class);
 map.put(element.getEnclosingElement().toString(), request.path());
 }
 }
 return false;
 }
 }
 
 | 
参考链接
- 公共技术点之 Java 注解 Annotation
- 深入理解Java注解类型(@Annotation)
- 自定义Java注解处理器
- 秒懂,Java 注解 (Annotation)你可以这样学
- Android 中注解的使用
- Java 基础(十七)注解