注解Annotation学习基础篇

1.Annotation是什么?
注解是JDK5新增的,主要为程序增加元数据。Annotation是一种接 口,主要用来对JAVA应用程序元素设置元数据。需要通过JAVA反射技术获得Annotation对象,根据Annotation对象实例获取程序元素上的元数据信息即Annotation信息。
2.如何定义Annotation?
定义注解Annotation很简单,通过关键字@interface即可定义一个注解。下图自定义一个注解。

        @Documented
        @Target(ElementType.METHOD)
        @Inherited
        @Retention(RetentionPolicy.RUNTIME)
        public @interface MethodInfo {
        // 作者
        String author() default "tonny";
        // 日期
        String date();
        }

3.哪些程序元素可以使用注解?
JAVA应用中哪些程序元素可以使用Annotation。在JDK中另外一个AnnotatedElement接口代表了程序中可以使用Annotation的程序元素,JDK中具体的实现类主要有:
3.1 Class:JAVA类从面可以使用注解Annotation.
3.2. Constructor:构造器可以使用注解Annotation。
3.3. Method:JAVA类中的方法可以使用注解Annotation
3.4. Field:JAVA类中的成员变量可以使用Annotation,Spring中 很多场景。
3.5. Package: 类的包定义上使用注解
4.注解特点
4.1.注解中可以定义方法,但都是无参的方法,即不能有任何参数。
4.2.注解中的方法可以有默认值,必须使用default 赋值。上述中,就是采用default进行赋值
4.3.注解中的方法名和返回类型就是注解中的成员变量名和变量类型
4.4.注解的返回类型只能是基本类型,String,枚举类型,Annotation类型和这些类型组成的数组–非常重要
4.5.注解中如果定义成员变量,如果成员变量没有默认值(即没有使用default进行赋值),则在使用该注解时必须对成员变量进行赋值。
4.6.注解中可以包含元注解,元注解被用来定义自定义注解
5.四个元注解
JDK中提供了4个元数据注解,这4个元注解可以注解自定义注解
5.1@Target:
5.1.1.主要表明使用@Target注解的范围,可以在哪些应用程序元素中使用。

        @Documented
        @Retention(RetentionPolicy.RUNTIME)
        @Target(ElementType.ANNOTATION_TYPE)
        public @interface Target {
            ElementType[] value();
        }

5.1.2.@Target的注解范围通过ElementType枚举类数组指定:

public enum ElementType {
    /** Class, interface (including annotation type), or             enum declaration */
    TYPE,

    /** Field declaration (includes enum constants) */
    FIELD,

    /** Method declaration */
    METHOD,

    /** Parameter declaration */
    PARAMETER,

    /** Constructor declaration */
    CONSTRUCTOR,

    /** Local variable declaration */
    LOCAL_VARIABLE,

    /** Annotation type declaration */
    ANNOTATION_TYPE,

    /** Package declaration */
    PACKAGE
}

5.1.3.上述程序中是元注释@Target源码,可以发现@target包含元注解,通过该ElementType.ANNOTATION_TYPE指明了注解的范围。
5.1.4.@Target注解的方法名为value,即成员变量名。返回类型为一个枚举ElementType。符合注解中方法的返回类型要求(枚举类型或枚举类型数组)
5.1.5.通常情况下使用注解中的方法时,应该使用”name=value”形式。即 上述程序中@Target(ElementType.ANNOTATION_TYPE)
应该为@Target(value = ElementType.ANNOTATION_TYPE)。如下情况特殊除外:
5.1.5.1如果自定义的注解中就含有一个成员变量而且成员变量的名称为value,则可以不需要使用name=value形式。
5.2@Retention
5.2.1使用@Retention修饰自定义的Annotation,表明该Annotation的声明周期

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    RetentionPolicy value();
}

5.2.2上述源码表明@Retention生命周期通过RetentionPolicy控制。RetentionPolicy为枚举类,主要包含3个数值:
5.2.2.1.RetentionPolicy.SOURCE:编译器直接丢弃这种策略。
5.2.2.2.RetentionPolicy.CLASS:编译器将Annotation记录在CLASS文件中,但是JVM在运行时会抛弃。这也是默认行为
5.2.2.3RetentionPolicy的源码如下:

public enum RetentionPolicy {
    /**
     * Annotations are to be discarded by the compiler.
     */
    SOURCE,

    /**
     * Annotations are to be recorded in the class file by the compiler
     * but need not be retained by the VM at run time.  This is the default
     * behavior.
     */
    CLASS,

    /**
     * Annotations are to be recorded in the class file by the compiler and
     * retained by the VM at run time, so they may be read reflectively.
     *
     * @see java.lang.reflect.AnnotatedElement
     */
    RUNTIME
}

5.3@Inherited
5.3.1@Inherited指定被它注解的Annotation将具有继承性质,如果某 个类使用了自定义注解A(A注解被@Inherited修饰),则A的子类也具有A注解的特性。
5.3.2@Inherited的源码如下,只是标记注解

    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.ANNOTATION_TYPE)
    public @interface Inherited {
    }

5.4@Documented
5.4.1.@Documented修饰的注解可以被javadoc工具文档化。也是一个标记注解,源码如下:

    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.ANNOTATION_TYPE)
    public @interface Documented {
    }

6.自定义注解
6.1自定义注解只需要使用@interface声明即可,如下定义了MethodInfo注解

@Documented
@Target(ElementType.METHOD)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodInfo {
    // 作者
    String author() default "tonny";
    // 日期
    String date();
    // 版本
    int version() default 1;
    // 注释
    String comments();
}

6.2.定义了AnnotationExample类,使用自定义注解,如下

public class AnnotationExample {

    @Override
    @MethodInfo(author="tonny",date="2016-08-11",comments="override toString method")
    public String toString(){
        return "Override toString method";
    }
    @Deprecated
    @MethodInfo(date="2016-08-11",comments="deprecated method")
    public void oldMethod(){
        System.out.println("deprecated method do not use it");
    }

    @SuppressWarnings(value = { "unchecked" })
    @MethodInfo(date="2016-08-11",comments="deprecated method")
    public List generateList(){
        List l = new ArrayList();
        l.add("a");
        l.add("b");
        return l;
    }
}

6.3.类AnnotationParse.java是一个简单的解析注解的小程序:

public class AnnotationParse {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        try {
            Method[] methods = AnnotationParse.class.getClassLoader()
            .loadClass("com.egfbank.annotaion.example1.AnnotationExample")
            .getMethods();
            for(Method m:methods){
                // getAnnotations()返回指定元素上所有的注释
                for(Annotation anno : m.getAnnotations()){
                    System.out.println("annotation : "+anno); 
                }            
                //检查 注解MethodInfo是否起到作用
                // 判断程序中指定元素上某个特定的注释是否存在
                if(m.isAnnotationPresent(MethodInfo.class)){
                    MethodInfo ma =  m.getAnnotation(MethodInfo.class);
                    System.out.println(ma.author());
                    System.out.println(ma.date());
                }
            }
        }catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

7.总结
7.1通过上述例子,可以看出注解必须和反射技术结合起来才能发挥重要的作用。灵活使用注解可以减少很多无用的代码的编写。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值