简介

注解是一系列元数据,它提供数据用来解释程序代码,但是注解并非是所解释代码本身的一部分。注解对于代码的运行效果没有直接影响。

主要作用

  • 提供信息给编译器: 编译器可以利用注解来探测错误和警告信息
  • 编译阶段时的处理: 软件工具可以用来利用注解信息来生成代码、Html文档或者做其它相应处理。
  • 运行时的处理: 某些注解可以在程序运行的时候接受代码的提取

定义

注解和类、接口等是一个层次的东西,它的声明是用@interface标识的,跟接口很像,如下所示:

public @interface Zeling {
}

元注解-注解的注解

@Documented

使用这个注解,可以让注解中的元素包含到javadoc或者类似的工具上去。

// Indicates that annotations with a type are to be documented by javadoc and similar tools by default.

@Target

限定运用场景,可以同时限定多个,比如说新定义一个注解,限定在类型和方法注解。

// Indicates the contexts in which an annotation type is applicable.

主要有以下几种:

    // 限定给类型注解,比如说类、接口、枚举等
    TYPE,

    // 限定给属性注解
    FIELD,

    // 限定给方法注解
    METHOD,

    // 限定给参数注解
    PARAMETER,

    // 限定给构造函数注解
    CONSTRUCTOR,

    // 限定给局部变量注解
    LOCAL_VARIABLE,

    // 限定在注解上注解
    ANNOTATION_TYPE,

    // 限定在包上使用注解
    PACKAGE

@Retention

保留期,即注解可以在什么时间段上起作用。

  • SOURCE 源代码阶段起作用
  • CLASS 到编译阶段还能起作用
  • RUNTIME 到运行期还能起作用

@Inherited

继承注解:当一个超类使用了这个注解,然后他的子类如果没有使用注解的话,那么子类可以继承超类的注解。

// 注解A
public @interface A {}

// 超类B
@A
public class B {}

// B的子类C
public class C extends B {}

那么,C也拥有注解A。

@Repeatable

可重复的,当一个注解A使用了这个可重复的注解,那么注解A可以多次注解在同一个地方。

public @interface Colors {
    Color[] value();
}

@Repeatable(Colors.class)
public @interface Color {
    String color() default "black";
}

@Color("purple")
@Color("brown")
@Color("red")
public class Pen {}

上面这个代码块就是这个注解的习惯用法,自己理解哈。

注解的属性

注解只有属性,没有方法。注解的属性定义跟无形参的方法很像。

public @interface A {
    // String 是属性的返回值,msg是属性的名称,可以用default后面跟着默认的值
    String msg() default "msg";
}

使用方式

@A(msg = "zeling")
public class B {}

如果注解属性中,只有一个属性,并且属性的名称为value那么可以直接在注解后面直接填值,不用写出属性名,如:

@C(value = "msg")
//等价于
@C("msg")

注解的运用

Class中有三个为注解提供的方法:

// 判断是否使用了注解
public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {}
// 获取某个注解
public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {}
// 获取所有注解
public Annotation[] getAnnotations() {}

例子:

@Zeling(msg = "zeling")
public class App {
    /**
     * @description TODO
     * @date 2018年1月31日 下午11:06:13
     * @param args
     */
    public static void main(String[] args) throws Exception {
        boolean flag = App.class.isAnnotationPresent(Zeling.class);
        if (flag) {
            Zeling zeling = App.class.getAnnotation(Zeling.class);
            System.out.println("annotation: " + zeling.msg());
        }
        
    }
}

结果:

annotation: zeling

PS:记得给注解Zeling的作用时段设置为RetentionPolicy.RUNTIME哦,不然你可看不到输出的。还有就是,注解的提取是基于反射机制的,而反射是比较耗时的,所以使用注解的时候请考虑时间成本。

结语

错误之处还请帮忙指正~


zeling
27 声望1 粉丝

文章不再维护,新站点:[链接]