java注解(1)

发布时间:2019-11-20 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了java注解(1)脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

参考:

  1. 秒懂,Java 注解 (Annotation)你可以这样学
  2. 疯狂java讲义

1. 定义

classsinterface 一样,注解也属于一种类型。
注解通过 @interface 关键字进行定义。

public @interface testAnnotation { }

2. 语法

默认情况下,Annotation可用于修饰任何程序元素,包括接口、类、方法等。

Annotation成员变量以方法形式定义

Annotation中的成员变量以无形参的方法形式来声明。定义了几个成员变量,在使用时必须给值。

public @interface MyTag {     String name();     int age(); }

有个默认值,在使用时可以不给值。

public @interface MyTag {     String name() default "hobe";     int age() default 18; }

Annotation

jdk除了java.lang下的5个基本Annotation:

  • @override(限定重写)
  • @DePRecated(标记过时)
  • @SupPressWarnings(抑制警告)
  • @SafeVARargs(java7)
  • @functionalInterface(java8)
  • @H_360_131@

    之外,java.lang.annotation包下提供了6个Meta Annotation(元Annotation),其中5个都用于修饰其他Annotation。主要几个如下:

    1 @Retention

    只能修饰Annotation定义,指定修饰多长时间,其码:

    @Documented @Retention(Retentionpolicy.RUNTIME) @Target(ElementTyPE.ANNOTATION_TYPE) public @interface Retention {     /**      * Returns the retention policy.      * @return the retention policy      */     RetentionPolicy value(); }

    其中只有一个成员变量。

    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 } 

    SOURCE:用于检查代码,编译时丢掉。(主要看IDE是否报错)
    CLASS:(默认)。编译后也会记录在class文件中。运行时,JVM不可获取Annotation信息,不可反射获取。
    RUNTIME:(通常会使用)。编译后也会记录在class文件中。运行时,JVM可获取Annotation信息,可反射获取

    使用示例

    @Retention(RetentionPolicy.RUNTIME) public @interface MyTag {     ... }

    或:

    @Retention(value = RetentionPolicy.RUNTIME) public @interface MyTag {     ... }

    说明

    当Annotation成员变量名value时,只需为value指定值时,可以在括号里直接写出value的值,无需name=value的形式

    2 @Target

    只能修饰Annotation定义。指定哪些程序单元可以使用,源码:

    @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Target {     /**      * Returns an array of the kinds of elements an annotation type      * can be applied to.      * @return an array of the kinds of elements an annotation type      * can be applied to      */     ElementType[] value(); }
    public enum ElementType {     /** Class, interface (including annotation type), or enum declaration */     TYPE,      /** Field declaration (includes enum constants) */     FIELD,      /** Method declaration */     METHOD,      /** Formal parameter declaration */     PARAMETER,      /** Constructor declaration */     CONSTRUCTOR,      /** Local variable declaration */     LOCAL_VARIABLE,      /** Annotation type declaration */     ANNOTATION_TYPE,      /** Package declaration */     PACKAGE,      /**      * Type parameter declaration      *      * @since 1.8      */     TYPE_PARAMETER,      /**      * Use of a type      *      * @since 1.8      */     TYPE_USE } 

    如只能修饰成员变量则使用:

    @Target({ElementType.FIELD})

    3 @Documented

    被该Annotation修饰的类将会被javadoc工具提取成文档。

    4 @InherITed

    被@Inherited修饰的注解,用于父类时,子类自动会加该注解。

    System.out.println(ChildClass.class.isAnnotationPresent(MyTag.class));

    true

    3. 自定义Annotation

    分类:标记Annotation元数据Annotation

    根据Annotation是否包含成员变量,将其分为两类:

    • 标记Annotation:没有定义成员变量,尽利用自身是否存在与否来提供信息。如@Test,@Override
    • 元数据Annotation:包含成员变量。

    注意的一种情况是一个注解没有任何属性。比如

    public @interface Perform {}

    那么在应用这个注解的时候,括号都可以省略。

    @Perform public void testMethod(){}

    示例

    @Target({ElementType.FIELD}) @Retention(value = RetentionPolicy.RUNTIME) public @interface MyTag {     String name() default "hobe"; //字符串     int age() default 18;  //int     String[] likes(); // 数组     Sex sex(); //枚举 }

    反射提取Annotation信息

    使用Annotation修饰了类、方法、成员变量等成员之后,这些Annotation并不会自己生效。必须由开发者提取信息并处理。
    java.lang.reflect增加了读取运行时Annotation的能力。如:

    • getAnnotation()
    • getAnnotations()
    • isAnnotationPresent()
    • getAnnotationsByType()
    • ...

    如获取Mytag注解中info方法上的所有注解,则:

     Class.forName("MyTag").getMethods("info").getAnnotations()

    使用示例

    • 注解类:
    @Target({ElementType.FIELD,ElementType.TYPE}) @Retention(value = RetentionPolicy.RUNTIME) public @interface MyTag {     String name() default "hobe"; //字符串     int age() default 18;  //int     String[] likes(); // 数组     Sex sex() default Sex.BOY; //枚举 }
    public enum Sex {     BOY,GIRL }
    • 工具类(这里工具类和被注解类放在一起了)
    @MyTag(likes = {"code","ball"}) public class Demo {     private String name;     private Integer age;     private String[] likes;     private Sex sex;      public static void main(String[] args) {         Demo demo = new Demo();         /** 仅仅注解,并不能将值赋给Demo的字段 */         System.out.println(demo);          boolean hasAnnotation = Demo.class.isAnnotationPresent(MyTag.class);         if (hasAnnotation){             MyTag myTag = Demo.class.getAnnotation(MyTag.class);             System.out.println(myTag.name());             System.out.println(myTag.likes());             System.out.println(myTag.sex());             System.out.println(myTag.age());         }     }     ... }

    结果:

    Demo{name='null', age=null, likes=null, sex=null} hobe [Ljava.lang.String;@4617c264 BOY 18

    参考:

    1. 秒懂,Java 注解 (Annotation)你可以这样学
    2. 疯狂java讲义

    脚本宝典总结

    以上是脚本宝典为你收集整理的java注解(1)全部内容,希望文章能够帮你解决java注解(1)所遇到的问题。

    如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

    本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
    如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。