zoukankan      html  css  js  c++  java
  • 二十七、JDK1.5新特性---Annotation

            上篇文章介绍了反射的一些基础知识以及应用案例,本文将介绍jdk 1.5 出现的新特性——Annotation也就是我们所说的注解,即使用注释的方式加入一些程序的信息。

    注解相当于一种标记,在程序中加了注解就等于为程序打上了某种标记,没加,则等于没有某种标记。

        Java.lang.annotation. Annotation 接口是所有的Annotation都必须实现的接口。下面我们将从系统的三个内建Annotation开始学习。

    内建Annotation

          ♥ @Overrider :复写的Annotation

            ♥ @Deprecated : 不赞成使用的Annotation,通常表示过时

            ♥ @SuppressWarnings :压制安全警告的Annotation

    Overrider作用与用法

            表示当前方法是在复写父类的方法,当我们复写父类的一个方法时可以在方法上面写上@ Overrider,其作用是验证该方法是否拼写错误,如果编写错误则编译失败。从而提高了程序的安全性

    Deprecated作用与用法

        通常表示当前方法不建议使用或者是已经因为某种原因已经过时,现在有更好的方法,从而保证程序的健壮性

    SuppressWarnings作用与用法

        用于压制强制警告信息,以之前介绍的泛型操作为例,在泛型中如果没有指定泛型类型则在编译时期会出现安全警告,而如果加上@SuppressWarnings则可以将安全警告强制压制。

    自定义Annotation

        当我们系统Annotation不能满足我们的需求时,我们就可以自定义Annotation。

    格式

    [public ] @interface Annotation 名称{ 
    
            数据类型 变量名称(); 
    
       }

            按照上述格式自定义一个简单的Annotation。

    public @interface MyDefaultAnnotationNoneParam{     
    
      }

            之后就可以直接在程序中使用@ MyDefaultAnnotationNoneParam了。

            此外还可以向Annotation中设置参数,使用变量接受参数

    public @interface MyDefaultAnnotationSingleParam{ 
    
        public String value() ;    // 接收设置的内容 
    
    }

             在使用的时候就必须指定变量的值

    @ MyDefaultAnnotationSingleParam("月芽之上") 
    
    class Demo{ 
    
    }

             或者也可以使用明确的标记,表示内容赋值给那个参数

    public @interface MyDefaultAnnotationMoreParam{ 
    
        public String key(); 
    
    public String value() ;    // 接收设置的内容 
    
    }

             此时Annotation在使用的时候需要设置两个参数。一个是key、一个事value.

    @ MyDefaultAnnotationMoreParam (key="月芽之上",value="李占祥") 
    
    class Demo{ 
    
    }

             也可以设置一个数据进去

    public @interface MyDefaultAnnotationArrayParam{ 
    
        public String[] value() ;    // 接收设置的内容 
    
    }

            接收的内容本身是一个数组类型,需要传递数据,这一点类似于SuppressWarnings

    @ MyDefaultAnnotationArrayParam ({ "月芽之上","李占祥"}) 
    
    class Demo{ 
    
    }

             以上所定义的全部的Annotation中有一个特点,就是所有的参数内容需要在使用注释的时候设置上去,那么也可以为一个参数设置默认的内容,在声明的时候使用default即可。

    public @interface MyDefaultAnnotationParam{ 
    
        public String key() default "月芽之上"; 
    
    public String value()default "李占祥" ;    // 接收设置的内容 
    
    }

             如果设置了默认值,那么在使用Annotation时就可以不设置内容了(使用默认值)。

            在以上操作中,对于一个Annotation而言 有时候会取固定的取值范围,只能取固定的几个值,那么这时候就需要依靠枚举来实现。

    public enum MyName{    // 定义枚举类型 
    
        月芽之上,李占祥; 
    
    }

            以后的Annotation的取值,只能从这两个值中间去取。

    public @interface MyDefaultAnnotationEnum{ 
    
        public String name() default MyName."月芽之上"; 
    
    }

             此时以上的Annotation已经设置好了一个枚举中的内容作为默认值,那外部在使用此Annotation的时候也需要从枚举的固定值中取。

    Retention和RetentionPolicy

        在定义Annotation时可以使用Retention定义一个Annotation的保存范围,此Annotation的定义如下:

    @Documented

    @Retention(vale=RUNTIME)

    @Target(vale=ANNOTATION_TYPE)

    public @interface Retention{

        RetentionPolicy value();

    }

            在以上的Retention定义中定义了一个RetentionPolicy的变量,此变量用于指定Annotation的保存范围。范围分为三种:

    在三个范围中,最需要关心的即使RUNTIME范围,因此此时在执行的时候气作用。

    通过反射取得Annotation内容

        一个Annotation如果要想变得有意义,就必须结合反射机制取得Annotation中设置的全部内容。

    取得Annotation内容的常见方法

    package reflectannotation ; 
    
    public class SimpleBeanOne{ 
    
        @SuppressWarnings("unchecked") 
    
        @Deprecated 
    
        @Override 
    
        public String toString(){ 
    
            return "Hello LiXingHua!!!" ; 
    
        } 
    
    }

            同时设置了三个Annotation,那么此时注意,只有Deprecated的Annotation定义的范围是RUNTIME范围,所以此时通过反射只能取得一个。

    import java.lang.annotation.Annotation ; 
    
    import java.lang.reflect.Method ; 
    
    public class ReflectDemo01{ 
    
        public static void main(String args[]) throws Exception{    // 所有异常抛出 
    
            Class <?> c = null ; 
    
            c = Class.forName("reflectannotation.SimpleBeanOne") ; 
    
            Method toM = c.getMethod("toString") ;    // 找到toString()方法 
    
            Annotation an[] = toM.getAnnotations() ;    // 取得全部的Annotation 
    
            for(Annotation a:an){    // 使用 foreach输出 
    
                System.out.println(a) ; 
    
            } 
    
        } 
    
    }

            以上的操作代码实际是通过三个系统内建的Annotation完成的,那么特可以自定义一个Annotation

    package reflectannotation ; 
    
    import java.lang.annotation.Retention ; 
    
    import java.lang.annotation.RetentionPolicy ; 
    
    @Retention(value=RetentionPolicy.RUNTIME)    // 此Annotation在类执行时依然有效 
    
    public @interface MyDefaultAnnotationReflect{ 
    
        public String key() default "月芽之上" ; 
    
        public String value() default "李占祥" ; 
    
    }

             以上的Annotation范围是在运行时依然有效,下面定义一个类使用该Annotation。

    package reflectannotation ; 
    
    public class SimpleBeanTwo{ 
    
        @SuppressWarnings("unchecked") 
    
        @Deprecated 
    
        @Override 
    
        @MyDefaultAnnotationReflect(key="月芽之上",value="李占祥") 
    
        public String toString(){ 
    
            return "Hello lzx!!!" ; 
    
        } 
    
    }

            下面通过反射取得指定的Annotation,因为现在唯一设置的内容就是MyDefaultAnnotationReflect

    import reflectannotation.MyDefaultAnnotationReflect ; 
    
    import java.lang.annotation.Annotation ; 
    
    import java.lang.reflect.Method ; 
    
    public class ReflectDemo02{ 
    
        public static void main(String args[]) throws Exception{    // 所有异常抛出 
    
            Class <?> c = null ; 
    
            c = Class.forName("reflectannotation.SimpleBeanTwo") ; 
    
            Method toM = c.getMethod("toString") ;    // 找到toString()方法 
    
            if(toM.isAnnotationPresent(MyDefaultAnnotationReflect.class)){ 
    
                // 判断是否是指定的Annotation 
    
                MyDefaultAnnotationReflect mda = null ; 
    
                mda = toM.getAnnotation(MyDefaultAnnotationReflect.class) ;    // 得到指定的Annotation 
    
                String key = mda.key() ;    // 取出设置的key 
    
                String value = mda.value() ;    // 取出设置的value 
    
                System.out.println("key = " + key) ; 
    
                System.out.println("value = " + value) ; 
    
            } 
    
        } 
    
    }
  • 相关阅读:
    回调函数
    BIRT实现组内跨行计算
    POJ 3616 Milking Time DP题解
    string的内存管理问题
    天津政府应急系统之GIS一张图(arcgis api for flex)解说(三)显示地图坐标系模块
    myeclipse将java项目转换成web项目,导出war包
    Spring之IOC篇章具体解释
    为RAC私有网络配置网卡Bonding
    聊聊高并发(九)实现几种自旋锁(四)
    鼠标放上去Div旋转特效代码
  • 原文地址:https://www.cnblogs.com/yueyazhishang/p/4065419.html
Copyright © 2011-2022 走看看