java · 2018-02-11 0

Java元注解和自定义注解及注解的使用

一、@Documented

@Documented 注解表明这个注解会被 javadoc 之类工具记录,即注解类型信息也会被包括在生成文档中。默认情况下,javadoc 是不包括注解的。

二、@Target

@Target 注解用于设定注解使用范围

  1. @Target(ElementType.TYPE) 接口、类、枚举、注解
  2. @Target(ElementType.FIELD) 字段、枚举的常量
  3. @Target(ElementType.METHOD) 方法
  4. @Target(ElementType.PARAMETER) 方法参数
  5. @Target(ElementType.CONSTRUCTOR) 构造函数
  6. @Target(ElementType.LOCAL_VARIABLE) 局部变量
  7. @Target(ElementType.ANNOTATION_TYPE) 注解
  8. @Target(ElementType.package)

这里可以使用多个,比如: @Target({ElementType.TYPE,ElementType.METHOD})

三、@Retention

@Retention 注解表明被保留到那个阶段. 有三个值:

  1. RetentionPolicy.SOURCE 这种类型的 Annotations 只在源代码级别保留,编译时就会被忽略,如@Override 注解
  2. RetentionPolicy.CLASS 这种类型的Annotations编译时被保留,在class文件中存在,但JVM将会忽略
  3. RetentionPolicy.RUNTIME 这种类型的Annotations将被JVM保留,所以他们能在运行时被JVM或其他使用反射机制的代码所读取和使用.

四、@Inherited

@Inherited 定义在类级别上,子类时可以继承的,@Inherited 定义在方法级别上,子类的方法如果复写的那么就不能继承。

五、自定义注解

1.@Test_Cat

可被 javadoc 记录,用于类上,可用反射机制读取

@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test_Cat {
    String catName() default "cat";
}

2.@Test_WhiteCat

可被 javadoc 记录,用于类上,可用反射机制读取

@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public  @interface Test_WhiteCat {
    String whiteCatName() default "white cat";
}

3.@Test_Dog

用于类上,可用反射机制读取,可被继承

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface Test_Dog {
    String dogName() default "dog";
}

4.@Test_BlackDog

用于类上,可用反射机制读取

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test_BlackDog {
    String blackDogName() default "black dog";
}

六、注解的使用

AnimalFather 类为父类,AnimalSon 为子类。AnimalSon 类继承 AnimalFather 类

@Test_Cat   //不可被继承
@Test_Dog   //可被继承
class AnimalFather{

}

@Test_WhiteCat
@Test_BlackDog
class AnimalSon extends AnimalFather{

}

七、测试

public class TestMain {

    public static void main(String[] args) {
        //反射获得AnimalSon
        Class<AnimalSon> clazz = AnimalSon.class;
        System.out.println("- - - - - - Annotation - - - - - -");
        for (Annotation annotation : clazz.getAnnotations()) {
            System.out.println(annotation);
        }
        System.out.println("- - - - - - Annotation Method - - - - - -");
        //如果有Test_Cat注解
        if (clazz.isAnnotationPresent(Test_Cat.class)) {
            Test_Cat cat = clazz.getAnnotation(Test_Cat.class);
            System.out.println(cat.catName());
        }
        //如果有Test_Dog注解
        if (clazz.isAnnotationPresent(Test_Dog.class)) {
            Test_Dog dog = clazz.getAnnotation(Test_Dog.class);
            System.out.println(dog.dogName());
        }
        //如果有Test_WhiteCat注解
        if (clazz.isAnnotationPresent(Test_WhiteCat.class)) {
            Test_WhiteCat whiteCat = clazz.getAnnotation(Test_WhiteCat.class);
            System.out.println(whiteCat.whiteCatName());
        }
        //如果有Test_BlackDog注解
        if (clazz.isAnnotationPresent(Test_BlackDog.class)) {
            Test_BlackDog blackDog = clazz.getAnnotation(Test_BlackDog.class);
            System.out.println(blackDog.blackDogName());
        }
    }
}

结果:

- - - - - - Annotation - - - - - -
@com.example.Test_Dog(dogName=dog)
@com.example.Test_WhiteCat(whiteCatName=white cat)
@com.example.Test_BlackDog(blackDogName=black dog)
- - - - - - Annotation Method - - - - - -
dog
white cat
black dog