annotation详解一

在项目开发中,自定义注解结合AOP是代码解耦合的一大利器,我经历的几个项目都有自定义注解,但对注解的了解并不深入,仅仅只局限于简单使用。今天抽空将自定义注解实践了一番,当做学习笔记。

我们先看看如何自定义注解,代码如下

@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Table {
    //表名
    String tableName() default "";
    //id字段名
    String id() default "id";
}

自定义注解由@interface来标识,自定义注解的特性由在它上面的几个特殊注解来传达,下面我们来一一研究下这几个有特殊含义的注解。

1.@Document

我们先来看jdk中Document源码中的注解,
Indicates that annotations with a type are to be documented by javadoc and similar tools by default. (添加在类型上的注解可以被javadoc生成文档)
这里写图片描述
此注解对运行等没有影响,仅在生成javadoc文档时会有体现。

@Inherited

Note that this meta-annotation type has no effect if the annotated type is used to annotate anything other than a class. Note also that this meta-annotation only causes annotations to be inherited from superclasses; annotations on implemented interfaces have no effect.

Inherited仅仅作用在注解类上,当查找的注解上这个Inherited时,isAnnotationPresent,getAnnotation这2个方法会一层层往超类中取查找。

public class Man extends User {
    /**
     * 性别
     */
    private int sex;
    /**
    * User上有@Table注解,Table注解上添加了@Inherited
    */
    public static void main(String[] args) {
        Class manClass = Man.class;
        System.out.println(manClass.isAnnotationPresent(Table.class));
        System.out.println(manClass.getAnnotation(Table.class));
    }
}
#### 结果  ####
true
@annotation.Table(id=id, tableName=user)

@Retention

retetion有如下几个取值,作用范围由小到大。
1.SOURCE:在源文件中有效(即源文件保留)
2.CLASS:在class文件中有效(即class保留)
3.RUNTIME:在运行时有效(即运行时保留)
只有RetentionPolicy为RUNTIME,class的isAnnotationPresent,getAnnotation等方法才有效。

@Target

限制注解可以作用在哪些位置,java8新增type_use和type_parameter的用法。
type_use可以用于标注任意类型(不包括class), type_parameter用来标注类型参数。
type_use几乎对标志位置没限制,当实际使用时最好还是type,field,method等更具体的使用场景。

@TypeUse
public class TypeAnnotationTest<@TypeParameter T> {

    private List<Map<String, String>> list = new ArrayList<Map<String, String>>();
    @TypeUse
    private String test;

    public static void main(String[] args) throws Exception {
        TypeVariable<Class<TypeAnnotationTest>>[] ss = TypeAnnotationTest.class.getTypeParameters();
        // 获取泛型参数上的注解值
        System.out.println(((TypeParameter) ss[0].getDeclaredAnnotations()[0]).value());
        // 获取TypeAnnotationTest类上的注解值
        System.out.println(((TypeUse) TypeAnnotationTest.class.getAnnotations()[0]).value());
        // 获取实际泛型参数
        ParameterizedType parameterizedType = (ParameterizedType) TypeAnnotationTest.class.getDeclaredField("list").getGenericType();
        System.out.println(parameterizedType.getActualTypeArguments()[0]);
    }

}

@Repeatable

repeatable为一个语法糖,允许对同一个声明式或者类型加上相同的 Annotation,等实际应用时在深入研究下。

猜你喜欢

转载自blog.csdn.net/u013179884/article/details/79794515