Android中的注解入门篇——Java注解

1. 注解的分类

  • 标准注解
    包括以下几种注解成为标准注解,这三种是在JDK5之后包含的标准注解(annotation)。
    Overide——表示该函数被覆盖重写
    Deprecated——表示该函数或者类被废弃,已经不再维护
    SuppressWarnings——表示告诉Java编译器关闭对这些方法、类、成员的警告

  • 元注解
    元注解表示用来自定义其他注解的注解,有以下四种。

    注解用法示例说明
    @Target@Target(ElementType.METHOD)表示该注解可以用于什么地方,可能的ElementType参数有:
    CONSTRUCTOR:构造器的声明
    FIELD:域声明(包括enum实例)
    LOCAL_VARIABLE:局部变量声明
    METHOD:方法声明
    PACKAGE:包声明
    PARAMETER:参数声明
    TYPE:类、接口(包括注解类型)或enum声明
    @Retention@Retention(RetentionPolicy.RUNTIME)表示需要在什么级别保存该注解信息。可选的RetentionPolicy参数包括:
    SOURCE:注解将被编译器丢弃
    CLASS:注解在class文件中可用,但会被VM丢弃
    RUNTIME:VM将在运行期间保留注解,因此可以通过反射机制读取注解的信息。
    @Documented@Documented将注解包含在Javadoc中
    @Inherited@Inherited允许子类继承父类中的注解

  • 在元注解基础上自定义的注解

2.自定义注解

没有元素的注解叫做标记注解(mark annotation),下面就是一个标记注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MarkAnnotation {

}

下面的MethodInfo是一个比较完整的注解

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Inherited
public @interface MethodInfo {

    String author() default "example@example.com";

    String date();

    int version() default 1;
}

在MethodInfo的实现上有以下几点

  • 通过 @interface 定义,注解名即为自定义注解名
  • 注解配置参数名为注解类的方法名,且:
    a. 所有方法没有方法体,没有参数没有修饰符,实际只允许 public & abstract 修饰符,默认为 public ,不允许抛异常
    b. 方法返回值只能是基本类型,String, Class, annotation, enumeration 或者是他们的一维数组
    c. 若只有一个默认属性,可直接用 value() 函数。一个属性都没有表示该 Annotation 为 Mark Annotation
  • 可以加 default 表示默认值

  • 注解的可用的类型包括以下几种:所有基本类型、String、Class、enum、Annotation、以上类型的数组形式。元素不能有不确定的值,即要么有默认值,要么在使用注解的时候提供元素的值。而且元素不能使用null作为默认值。注解在只有一个元素且该元素的名称是value的情况下,在使用注解的时候可以省略“value=”,直接写需要的值即可。

3.注解的使用

还是以上面的MethodInfo为例,该注解是一个方法注解。

public Example{
    @MethodInfo(author="gaoyan", date="2015-05-30", version=2)
    public boolean isGoodExample() {
        return true;
    }
    @MethodInfo(date="2015-05-30")
    public boolean isBadExample() {
        return false;
    }
}

4.注解的解析

  • 运行时的Annotation解析
    对于@Retention(RetentionPolicy=RUNTIME)、@Target(ElementType.METHOD)的Annotation,可以使用下面的API解析:
method.getAnnotation(AnnotationName.class);
method.getAnnotations();
method.isAnnotationPresent(AnnotationName.class);

其他 @Target 如 Field,Class 方法类似

  • getAnnotation(AnnotationName.class) 表示得到该 Target 某个 Annotation 的信息,因为一个 Target 可以被多个 Annotation 修饰
  • getAnnotations() 则表示得到该 Target 所有 Annotation
  • isAnnotationPresent(AnnotationName.class) 表示该 Target 是否被某个 Annotation 修饰
public static void main(String[] args) {
    try {
        Class cls = Class.forName("Example");
        for (Method method : cls.getMethods()) {
            MethodInfo methodInfo = method.getAnnotation(
MethodInfo.class);
            if (methodInfo != null) {
                System.out.println("method name:" + method.getName());
                System.out.println("method author:" + methodInfo.author());
                System.out.println("method version:" + methodInfo.version());
                System.out.println("method date:" + methodInfo.date());
            }
        }
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
}
  • 编译时的Annotation解析
    编译时 Annotation 指 @Retention 为 CLASS 的 Annotation,甴编译器自动解析。需要做的

    • 自定义类集成自 AbstractProcessor
    • 重写其中的 process 函数

    假设 MethodInfo 的 @Retention 为 CLASS,解析示例如下:

@SupportedAnnotationTypes({ "MethodInfo" })
public class MethodInfoProcessor extends AbstractProcessor {

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment env) {
        HashMap<String, String> map = new HashMap<String, String>();
        for (TypeElement te : annotations) {
            for (Element element : env.getElementsAnnotatedWith(te)) {
                MethodInfo methodInfo = element.getAnnotation(MethodInfo.class);
                map.put(element.getEnclosingElement().toString(), methodInfo.author());
            }
        }
        return false;
    }
}

SupportedAnnotationTypes 表示这个 Processor 要处理的 Annotation 名字。
process 函数中参数 annotations 表示待处理的 Annotations,参数 env 表示当前或是之前的运行环境
process 函数返回值表示这组 annotations 是否被这个 Processor 接受,如果接受后续子的 rocessor 不会再对这个 Annotations 进行处理

  1. 参考https://github.com/android-cn/android-open-project-analysis/blob/master/tech/annotation.md
  2. 参考 http://www.cnblogs.com/pepcod/archive/2013/02/16/2913474.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值