• Java注释@interface的用法


       java用  @interface Annotation{ } 定义一个注解 @Annotation,一个注解是一个类。
    @Override,@Deprecated,@SuppressWarnings为常见的3个注解。
    注解相当于一种标记,在程序中加上了注解就等于为程序加上了某种标记,以后,
    JAVAC编译器,开发工具和其他程序可以用反射来了解你的类以及各种元素上有无任何标记,看你有什么标记,就去干相应的事。

          注解@Override用在方法上,当我们想重写一个方法时,在方法上加@Override,当我们方法
    的名字出错时,编译器就会报错,如图:


           注解@Deprecated,用来表示某个类的属性或方法已经过时,不想别人再用时,在属性和方法
    上用@Deprecated修饰,如图:

     

      注解@SuppressWarnings用来压制程序中出来的警告,比如在没有用泛型或是方法已经过时的时候,
     如图:

     

    注解@Retention可以用来修饰注解,是注解的注解,称为元注解。
    Retention注解有一个属性value,是RetentionPolicy类型的,Enum RetentionPolicy是一个枚举类型,
    这个枚举决定了Retention注解应该如何去保持,也可理解为Rentention 搭配 RententionPolicy使用。RetentionPolicy有3个值:CLASS  RUNTIME   SOURCE
    用@Retention(RetentionPolicy.CLASS)修饰的注解,表示注解的信息被保留在class文件(字节码文件)中当程序编译时,但不会被虚拟机读取在运行的时候;
    用@Retention(RetentionPolicy.SOURCE )修饰的注解,表示注解的信息会被编译器抛弃,不会留在class文件中,注解的信息只会留在源文件中;
    用@Retention(RetentionPolicy.RUNTIME )修饰的注解,表示注解的信息被保留在class文件(字节码文件)中当程序编译时,会被虚拟机保留在运行时,
    所以他们可以用反射的方式读取。RetentionPolicy.RUNTIME 可以让你从JVM中读取Annotation注解的信息,以便在分析程序的时候使用.

      1         package com.self;  
      2         import java.lang.annotation.Retention;  
      3         import java.lang.annotation.RetentionPolicy;  
      4           
      5         @Retention(RetentionPolicy.RUNTIME)  
      6         public @interface MyTarget  
      7         { }  
      8         定义个一注解@MyTarget,用RetentionPolicy.RUNTIME修饰;  
      9         package com.self;  
     10         import java.lang.reflect.Method;  
     11         public class MyTargetTest  
     12         {  
     13          @MyTarget  
     14          public void doSomething()  
     15          {  
     16           System.out.println("hello world");  
     17          }  
     18            
     19          public static void main(String[] args) throws Exception  
     20          {  
     21           Method method = MyTargetTest.class.getMethod("doSomething",null);  
     22           if(method.isAnnotationPresent(MyTarget.class))//如果doSomething方法上存在注解@MyTarget,则为true  
     23           {  
     24            System.out.println(method.getAnnotation(MyTarget.class));  
     25           }  
     26           }  
     27         }  
     28         上面程序打印:@com.self.MyTarget(),如果RetentionPolicy值不为RUNTIME,则不打印。  
     29           
     30          @Retention(RetentionPolicy.SOURCE )  
     31         public @interface Override  
     32           
     33         @Retention(RetentionPolicy.SOURCE )  
     34         public @interface SuppressWarnings  
     35           
     36         @Retention(RetentionPolicy.RUNTIME )  
     37         public @interface Deprecated  
     38         由上可以看出,只有注解@Deprecated在运行时可以被JVM读取到  
     39           
     40         注解中可以定义属性,看例子:  
     41         @Retention(RetentionPolicy.RUNTIME)  
     42         public @interface MyAnnotation  
     43         {  
     44          String hello() default "gege";  
     45           String world();  
     46           int[] array() default { 2, 4, 5, 6 };  
     47           EnumTest.TrafficLamp lamp() ;  
     48           TestAnnotation lannotation() default @TestAnnotation(value = "ddd");  
     49           Class style() default String.class;  
     50         }  
     51         上面程序中,定义一个注解@MyAnnotation,定义了6个属性,他们的名字为:  
     52         hello,world,array,lamp,lannotation,style.  
     53         属性hello类型为String,默认值为gege  
     54         属性world类型为String,没有默认值  
     55         属性array类型为数组,默认值为2,4,5,6  
     56         属性lamp类型为一个枚举,没有默认值  
     57         属性lannotation类型为注解,默认值为@TestAnnotation,注解里的属性是注解  
     58         属性style类型为Class,默认值为String类型的Class类型  
     59           
     60         看下面例子:定义了一个MyTest类,用注解@MyAnnotation修饰,注解@MyAnnotation定义的属性都赋了值  
     61         @MyAnnotation(hello = "beijing", world="shanghai",array={},lamp=TrafficLamp.RED,style=int.class)  
     62         public class MyTest  
     63         {  
     64          @MyAnnotation(lannotation=@TestAnnotation(value="baby"), world = "shanghai",array={1,2,3},lamp=TrafficLamp.YELLOW)  
     65          @Deprecated  
     66          @SuppressWarnings("")  
     67          public void output()  
     68          {  
     69           System.out.println("output something!");  
     70          }  
     71         }  
     72          接着通过反射读取注解的信息:  
     73         public class MyReflection  
     74         {  
     75          public static void main(String[] args) throws Exception  
     76          {  
     77           MyTest myTest = new MyTest();  
     78             Class<MyTest> c = MyTest.class;  
     79             Method method = c.getMethod("output", new Class[] {});  
     80                //如果MyTest类名上有注解@MyAnnotation修饰,则为true  
     81           if(MyTest.class.isAnnotationPresent(MyAnnotation.class))  
     82           {  
     83            System.out.println("have annotation");  
     84           }  
     85            if (method.isAnnotationPresent(MyAnnotation.class))  
     86            {  
     87            method.invoke(myTest, null); //调用output方法  
     88            //获取方法上注解@MyAnnotation的信息  
     89              MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);  
     90             String hello = myAnnotation.hello();  
     91            String world = myAnnotation.world();  
     92            System.out.println(hello + ", " + world);//打印属性hello和world的值  
     93            System.out.println(myAnnotation.array().length);//打印属性array数组的长度  
     94            System.out.println(myAnnotation.lannotation().value()); //打印属性lannotation的值  
     95            System.out.println(myAnnotation.style());  
     96            }  
     97             //得到output方法上的所有注解,当然是被RetentionPolicy.RUNTIME修饰的  
     98              Annotation[] annotations = method.getAnnotations();  
     99               for (Annotation annotation : annotations)  
    100           {  
    101            System.out.println(annotation.annotationType().getName());  
    102           }  
    103            }  
    104         }  
    105         上面程序打印:  
    106         have annotation  
    107         output something!  
    108         gege, shanghai  
    109         3  
    110         baby  
    111         class java.lang.String  
    112         com.heima.annotation.MyAnnotation  
    113         java.lang.Deprecated  
    114           
    115         如果注解中有一个属性名字叫value,则在应用时可以省略属性名字不写。  
    116         可见,@Retention(RetentionPolicy.RUNTIME )注解中,RetentionPolicy.RUNTIME是注解属性值,属性名字是value,  
    117         属性的返回类型是RetentionPolicy,如下:  
    118         public @interface MyTarget  
    119         {  
    120             String value();  
    121         }  
    122         可以这样用:  
    123           @MyTarget("aaa")  
    124          public void doSomething()  
    125          {  
    126           System.out.println("hello world");  
    127          }  
    128            
    129         注解@Target也是用来修饰注解的元注解,它有一个属性ElementType也是枚举类型,  
    130         值为:ANNOTATION_TYPE CONSTRUCTOR  FIELD LOCAL_VARIABLE METHOD PACKAGE PARAMETER TYPE  
    131         如@Target(ElementType.METHOD) 修饰的注解表示该注解只能用来修饰在方法上。  
    132         @Target(ElementType.METHOD)  
    133         @Retention(RetentionPolicy.RUNTIME)  
    134         public @interface MyTarget  
    135         {  
    136          String value() default "hahaha";  
    137         }  
    138         如把@MyTarget修饰在类上,则程序报错,如:  
    139         @MyTarget  
    140         public class MyTargetTest  
    141         注解大都用在开发框架中吧,好了有关注解就学习那么多了,谢谢。 
  • 相关阅读:
    <Yii 学习>写入日志
    微信支付:curl出错,错误码:60
    PHPstorm创建注释模版
    Yii 常用命令
    Linux启动/停止/重启Mysql数据库的方法
    php foreach跳出本次/当前循环与终止循环方法
    介绍Sublime3下两款Markdown插件
    规范
    业务流程时序图
    数据字典
  • 原文地址:https://www.cnblogs.com/blogzhangwei/p/4670436.html
Copyright © 2020-2023  润新知