Java Annotation

Annotation(注解)

    JDK5开始,java增加了对元数据(MetaData)的支持,也就是Annotation(注解)。通过使用Annotation,开发人员在不改变原有逻辑的情况下,在源文件中嵌入一些补充的信息,用于对代码进行说明。Annotation 可以对包、类、接口、字段、方法参数、局部变量等进行注解。

    一、java自带的基本注解

        @Override(指定方法覆载)

        @Deprecated(标识方法或类过时)

        @SuppressWarnings(抑制编译器警告)

/**
     * @Override的作用是告诉编译器检查这个方法,保证这个父类包含一个被该方法重写的方法
     */
    @Override
    public String toString() {
        return "重写了toString方法";
    }
     
    /**
     * @Deprecated用于表示某个程序元素(类,方法等)已过时
     */
    @Deprecated
    public void deprecatedTest() {
        System.out.println("我是一个过时的方法");
    }
     
    /**
     * @SuppressWarnings用户抑制编译警告
     */
    @SuppressWarnings("rawtypes")
    public void suppressWarningsTest() {
        List l = new ArrayList<>();
    }

二、元注解(用于定义注解的注解)

        @Retention(标明注解被保留的阶段):只能修饰一个Annotation定义,用于指定被修饰的Annotation可以保留多长时间,

该注解包含一个RetentionPolicy类型的value的成员变量,所以使用@Retention注解时必须为该value指定值。RetentionPolicy是一个枚举类,值有三个:

                        RetentionPolicy.SOURCE:注解只保留在源代码中,编译器会直接丢弃这个注解

                        RetentionPolicy.CLASS:编译器将把注解记录在class文件中,当java程序运行时,Jvm不再保留Annotation。

                        RetentionPolicy.RUNTIME:编译器将把注解记录在class文件中,当java程序运行时,Jvm也会保留Annotation,程序可以通过反射获取该Annotation信息。

        @Target(标明注解使用的范围):只能修饰一个Annotation定义,它用户指定被修饰的Annotation能用于修饰哪些程序单元,,该注解包含一个ElementType类型的value的成员变量。

                        ElementType.TYPE:只能修饰类,接口或枚举定义

                        ElementType.FIELD:只能修饰成员变量

                        ElementType.METHOD:只能修饰方法

                        ElementType.PARAMETER:只能修饰参数

                        ElementType.CONSTRUCTOR:只能修饰构造器

                        ElementType.LOCAL_VARIABLE:只能修饰局部变量

                        ElementType.ANNOTATION_TYPE:只能修饰Annotation

                        ElementType.PACKAGE:只能修饰包定义

/**
 * 这个自定义注解用于方法上,且在程序运行时时,可以通过反射获取到该注解的信息
 * @author rdb
 *
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Testable {}

@Documented(标明是否生成javadoc文档):用于指定被该Annotation修饰的Annotation类将被javadoc工具提取成文档。

        @Inherited(标明注解可继承):用于指定被该Annotation修饰的Annotation类将具有继承性。

/**
 * 这个自定义注解用于某类上,该类的子类也会有@Testable注解
 * @author rdb
 *
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Inherited
public @interface Testable {}

三、自定义注解

        1)使用关键字@interface就可以定义一个新的注解

/**
 * 默认情况下Annotation可以修饰任何元素(类,接口,方法等)
 * Annotation可以自带成员变量,如果成员变量没有指定初始值,则在使用Annotation是应该为成员变量指定值,有默认值则可以不指定,但也可以指定覆盖默认值。
 * @author rdb
 *
 */
@Retention(RetentionPolicy.RUNTIME)
public @interface Testable {
    String name();
    int age();
    int pwd() default 123;
}

 2)提取Annotation信息

        当开发者使用了Annotation修饰了类、方法等成员后,Annotation不会自己生效,必须由开发着自己提供相应的工具来提取并处理Annotation信息。

        在java.lang.reflect包下有个AnnotatedElement接口,基本所有程序元素(Class,Constructor,Filed,Method,Package)都是它的实现类,所以程序通过反射获取了某个类的AnnotatedElement对象后,程序就可以通过AnnotatedElement对象的方法获取Annotation信息。

public class AnnotationTest {
 
    @Testable(age = 18, name = "rdb")
    public void info() {
        System.out.println("info");
    }
 
    @Test
    public void test() throws Exception {
        // 通过getAnnotations()返回所有注解
        Annotation[] annotations = Class.forName("com.shtel.test.annotation.AnnotationTest").
            getMethod("info").getAnnotations();
        for (Annotation a : annotations) {
            System.out.println(a);
            // 获取注释里的元数据
            if (a instanceof Testable) {
                System.out.println(((Testable) a).name());
                System.out.println(((Testable) a).age());
                System.out.println(((Testable) a).pwd());
            }
        }
        // 通过getAnnotation()获取具体的注解
        Annotation annotation = Class.forName("com.shtel.test.annotation.AnnotationTest").
            getMethod("info").getAnnotation(Testable.class);
        System.out.println(annotation);
 
        // 通过isAnnotationPresent()方法判断是否存在指定类型的注解
        Boolean b = Class.forName("com.shtel.test.annotation.AnnotationTest").getMethod("info")
                .isAnnotationPresent(Testable.class);
        System.out.println(b);
    }
 
}

 

posted @ 2019-03-20 10:01  技术小白丁  阅读(277)  评论(0编辑  收藏  举报