码迷,mamicode.com
首页 > 编程语言 > 详细

深耕静禅_Java_注解_2020年4月5日21:44:24

时间:2020-04-05 22:40:24      阅读:83      评论:0      收藏:0      [点我收藏+]

标签:item   注释   start   一个   san   方法   xtend   field   element   

  当午之急乃是将本命语言学好,虽为Java讲师,但深知自己斤两。其实客观讲,讲师才是最无知之编程人员,无有实战,不知市场,不知最新技术和痛点,井底观天教授井下的蝌蚪如何应对外面的世界,实则自我都未曾走出过。

  经历昨日赶稿,今终于学到注解。忽而进度下降,对我来说,定一个较远的目标然后有前提的实现,工作起来将甚快。——2020年4月5日21:41:10

何为注解

  • 自第五版引入新注释机制,一称为标注。

  • 可作用于类、方法、变量、参数及包,可以反射方式获取其标注的成员其内容。

  • 标注将于编译时融入字节码中,虚拟机保留标注内容,运行时获取其内容。

  • 注解可自定义,亦有已经建好的注解:

    • 可作用于代码:

      注解作用
      @Override 标注方法是否为重写方法,发现其父后将执行检查,若并非重写之法则编译报错。
      @Deprecated 标记方法是否过期,使用此方法时会编译警告。
      @SuppressWarnings 指示编译时忽略的警告。
    • 元注解,即最基础的,可注解其他注解的:

      注解作用
      @Retention 标识注解存在于何处:代码,class文件,运行时反射获得。
      @Documented 标识注解是否包含在用户文档中。
      @Target 标识注解应作用于哪种Java成员。
      @Inherited 标记注解父注解是哪个,默认没有任何父
  • 自七版本之后,新增三注解:

    注解作用
    @SafeVarargs (Java7)忽略所有使用参数为泛型变量的方法或构造方法的调用警告。
    @FunctionalInterface (Java8)标识匿名函数或函数式接口。
    @Repeatable (Java8)标识注解可在一声明上重复使用。

组成要素

父接口 Annotation

  • Annotation是所有注解的父接口。

    package java.lang.annotation;
    public interface Annotation {
    ?
        boolean equals(Object obj);
    ?
        int hashCode();
    ?
        String toString();
    ?
        Class<? extends Annotation> annotationType();
    }

元素类型 ElementType

  • ElementType表示注解所作用之成员。

  • 一个注解可与一个或多个成员进行关联,即在属性上添加的注解亦可在方法上添加。

  • 采用一个枚举来表示所有元素类型,位于java.lang.annotation中:

    package java.lang.annotation;
    ?
    public enum ElementType {
        TYPE,               /* 类、接口(包括注释类型)或枚举声明  */
    ?
        FIELD,              /* 字段声明(包括枚举常量)  */
    ?
        METHOD,             /* 方法声明  */
    ?
        PARAMETER,          /* 参数声明  */
    ?
        CONSTRUCTOR,        /* 构造方法声明  */
    ?
        LOCAL_VARIABLE,     /* 局部变量声明  */
    ?
        ANNOTATION_TYPE,    /* 注释类型声明  */
    ?
        PACKAGE             /* 包声明  */
    }

编译策略 RetentionPolicy

  • RetentionPolicy意为注解之策略,通俗可理解为注解可活动于哪个运行时机,编译期间或是class文件中,或是运行的时候。

  • 每个注解只能拥有一个策略。

  • 注解策略用一个枚举类统计描述,位于java.lang.annotation中:

    package java.lang.annotation;
    public enum RetentionPolicy {
        SOURCE,/* Annotation信息仅存在于编译器处理期间,编译器处理完之后就没有该Annotation信息了  */
    ?
        CLASS,/* 编译器将Annotation存储于类对应的.class文件中。默认行为  */
    ?
        RUNTIME/* 编译器将Annotation存储于class文件中,并且可由JVM读入 */
    }

分析已有注解

注解介绍
@Deprecated 注解不建议使用的成员。
@Override 只可标注方法,意为该方法覆盖了父类方法。
@Documented 所标注成员将出现于Javadoc中。
@Inherited 只能标注其他注解,表示其具有继承性。
@Retention 只能标注注解,指定其策略,即运行时机。
@Target 只能标注注解,指定其可作用的成员。
@SuppressWarnings 标注警告,将其静默。

Deprecated

@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Deprecated {
}
  1. 此注解的介绍可出现于Javadoc中。

  2. 此注解运行与运行时,即被编译进入class文件且被虚拟机加载。

  3. 其无target规定,则表示其可标注于任意成员中。

  4. 此注解主要用于标注某类中已过期的成员,若在其他类中调用本类过期方法,即出现警告。

Inherited

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}
  1. 此注解的介绍可出现于Javadoc中。

  2. 此注解运行与运行时,即被编译进入class文件且被虚拟机加载。

  3. Target指示其只能加载注解上。

  4. 此注解所修饰的注解被加载到类上后,其子类也将拥有此注解,此称为继承性,即代代相传此注解。

SuppressWarnings

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
    String[] value();
}
  1. Target指示其作用的范围,可位于类、接口、枚举、字段、方法、参数、构造方法、局部变量上。

  2. 策略指示其仅存于编译器处理期间,编译后不会存在于class文件中。

  3. 此注解可用于以上成员,以消除其中的各类警告:

    //消除方法中“已过期”方法的警告
    @SuppressWarnings(value={"deprecation"})
    public static void doSomething(){
        Date date = new Date(113, 8, 26);
        System.out.println(date);
    }
  4. 可在其value后大括号中添加需消除的警告类型:

    类型
    deprecation 不赞成或过期方法。
    unchecked 执行未检查转换,例如未用泛型的集合。
    fallthrough switch单个case没有break而直接运行下去造成的报警。
    path 类路径或文档路径有不存在路径。
    serial 在可序列化类中缺少 serialVersionUID 定义。
    finally finally子句不得正常完成。
    all 所有警告类型。

创建注解

  • 如上文已有注解类似,可使用@interface来创建自定义注解。

  • 可加注解于其上,其可加于其他注解之上注解即为已有注解,或称“元注解”。

    @Documented     //注解介绍可解析与文档中
    @Retention(RetentionPolicy.RUNTIME)     //运行时即可获取此注解
    @Target({Element.TYPE,ElementType.METHOD})      //可用于类、接口、方法
    @Inherited      //此注解所加类其子类可获得其注解
    public @interface MyAnnotation(){}//创建注解
  • 注解中可存在特殊变量声明,位于注解使用时赋值所用。其存在类型且名称自定,default后可赋值其默认值:

    public @interface MyAnnotation(){
        public String value() default "";//创建名为value且默认值为空字符串变量
    }
  • 上文注解可作用于其所指定成员之上:

    @MyAnnotation(value = ‘TestAnnotation‘)
    public class Test{}
  • 通过反射中的isAnnotationPresent方法,可查看类与注解的关系,例如查看是否被某注解所注:

    Class<Test> test = Test.class;  //反射到所注类
    Class<MyAnnotation> an = MyAnnotation.class;    //反射到注解类
    boolean flag = testClass.isAnnotationPresent(an);   //使用方法进行检测

反射获取注解

  • 注解之用,与反射息息相关,需将其进行反射且反射到其所作用之成员,继而将成员反射绑定至正在运行之类成员上。

  • 此处创建一注解为例,以备下文使用:

    @Target({ElementType.TYPE, ElementType.FIELD,ElementType.CONSTRUCTOR,ElementType.METHOD 
    })  //此注解可加与任意类型中
    @Retention(RetentionPolicy.RUNTIME)     //位于运行时获取此注解
    public @interface Info { 
       String value(); 
         //此处还可以继续添加 
         //String value2(); 
    }
    // 注解加于类
    @Info("Class Info")
    public class Hello {
        //加于属性
        @Info("Age Info")
        private int age;
        
      // 加于方法
        @Info("SetAge Info")
        public void setAge(int age){
            this.age = age;
        }
        
        // 加于构造方法
        @Info("Function Info")
        public Hello(){}
    }
  • 获得加在注解之上的或者类之上的注解或元注解:

    Annotation[] as = Info.class.getAnnotations();
    for (Annotation a: as) {
        System.out.println(a);
    }
    /*
        @java.lang.annotation.Documented()
        @java.lang.annotation.Target(value=[TYPE])
    */
  • 通过同样的方式亦可反射类中属性及方法之注解。

深耕静禅_Java_注解_2020年4月5日21:44:24

标签:item   注释   start   一个   san   方法   xtend   field   element   

原文地址:https://www.cnblogs.com/agoodjavaboy/p/12628873.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!