Java Annotation 注释类的 Retention 和重复注释

注释(@annotation):

metadata 元数据格式,提供信息给编译器,oracle 文档讲解怎么在编程中高效地使用注释类;
简述:注释是元数据,提供描述程序的数据,并不是程序本身的一部分;被注释的代码,在操作上并不会有什么区别;注意:注释类的参数的形式是:方法;并不是字段,在编译器运行时,应该重载并调用该方法,该方法会返回一个在注释时,写进入的值,如:@Schedules(dayOfMonth="last")
用途
① 给编译器提供信息;注释可以被编译器使用,去探查 errors 和 SuppressWarnings;
② 编译期和部署期加工:一些软件工具可以处理加工注释信息,生成代码或者xml文件等;
③ 运行期加工处理:可以在运行期检查一些注释,如springboot的那些注释吧;
所在包:一般在 java.lang | java.lang.annotation
用的地点:类、字段、方法、程序其他元素的声明:

  • Class instance creation expression: new @Interned MyObject();
  • Type cast: myString = (@NonNull String) str;
  • implements clause: class UnmodifiableList implements @Readonly List<@Readonly T> { ... }
  • Thrown exception declaration: void monitorTemperature() throws @Critical TemperatureException { ... }

简单格式:@Entityclass user{...}
注释的元素:注释可以包含 elements,可以在注释时,输入值:@SuppressWarnings(value="unchecked");
并且当注释只有一个 String 类型的元素时,可以省略 value,如下:@SuppressWarnings("unchecked")


重复注释(Java8支持):@Author(name = "Jane Doe")@Author(name = "John Smith")class MyClass { ... }
创建一个注释:格式:@interface name{}
注释的提取
使用Class myC=Class.forName("qualifiedName") 获取一个类;(只适合获取1个类,想要获取一个目录下的所有类,应该要后面的知识了);
myC.isAnnotationPresent(CustomAnnotation.class); 通过该函数判断指定 Annotation 是否出现在该类上(只适用于 Target 为 Type 的);
如果有这个注释,则使用:CustomAnnotation ca = (CustomAnnotation)myC.getAnnotation(CustomAnnotation.class);
注意:该方法返回值是 ,所以需要强制转换 cast;
同时在这一步也可以对类中方法 method 进行判断:Method[] ms = myC.getMethods(); 其方法与类上注释判断类似,后不详述;
获取注释的元素值:ca.value() 等等;方法已经在注释的代码体中写出;
注意:能够使用上述方法查到的注释类,其应该要保留到运行时,即必须显式写上 @Retention(RetentionPolicy.RUNTIME) 才可以(因为@Retention隐式为保留到编译时),否则该注释不会被 JVM 加载到内存中,无法使用反射,经过实例测试,确实如此;
通过这个,就可以知道 springboot 应该就是对 SpringApplication 类所在的目录下,所有包中的所有类进行扫描,判断是否有 @Component 等注释,如果有,则使用 Class.forName() 生成该类,并注入到容器中;


部分Java预定义的注释:

@Deprecated :表示被注释的元素是弃用的,应该不要使用;当在程序中使用了被@Deprecated 注释的类、字段、方法时,编译器会打印警告;
@Override:提示编译器该方法会重载父类的方法;@SuppressWarnings("{...}"):使用这个可以抑制2种类型的警告:"deprecatation"、"unchecked";
@SafeVarargs:当应用到方法或构造器上,会断言代码在可变参数上没有执行潜在的危险操作;当使用该注释时,与varargs相关的unchecked警告将会被抑制 suppress;
@FunctionalInterface:指示一个类型是函数式接口形式,用于函数式编程中;
@Native:用在字段-常量上,指示一个字段可能援引自 native 代码,即 C\C++;应用到其他注释的注释:被称为 meta-annotations,元注释;下面是几个


java.lang.annotation 里面的几个元注释:

@Retention(保持、保留、注意力):隐式默认为编译时;指示一个注释要保留到什么时候:RetentionPolicy.SOURCE-仅到源码时、RetentionPolicy.CLASS-仅保存到编译时、RetentionPolicy.RUNTIME-一直保存到运行时
说明:如果没有使用 @Retention@Document:被其注释的注释,只要被使用,该注释的元素就会被 Javadoc 工具记录成文本;(默认情况下,注释没有被 javadoc 工具包含)
@Target:严格指定一个注释可以用在哪种Java元素上,有如下Java元素:ElementType.ANNOTATIONTYPE(后面用x代表ElementType)、x.TYPE、x.CONSTRUCTOR、x.FIELD、x.METHOD、x.LOCAL_VARIABLE、x.PACKAGE、x.PARAMETER
@Inherited:被这个注解注释的注解,当其用在一个类 A 时,在 A 的子类 B 上查询一个注释,若 B 查询不到该注释,会前往 A 的注释上去查询;具体用处需要深入了解;
@Repeatable:指示一个注释,其标记注解一个类或声明时,可以出现多次;


类型检查:JavaSE8 没有提供内嵌的类型检查注释类型,但spring有,好像在SpringUtil里面,包含Springboot判空、判类型的那些注释
重复注释 RepeatAnnotation:JavaSE8后,允许重复注释,有时候重复注释会有用,如:@Schedule(dayOfMonth="last")@Schedule(dayOfWeek="Fri",hour="23")void invokeAtIndicatedTime(){...}上面的方法将会在每月的最后一天、每周5的23点进行调用;重复注释不仅用于方法上,还可以在任何允许注释的地方使用重复注释;说明:在一个注释类未声明重复之前,重复使用它会造成编译期间错误;注释类型设计:注释类型设计时,应该仔细考虑很多东西:是否可重复注释?可以注释哪些位置:类?字段?方法?以及注释要保留到什么时候?


创建一个可重复注释的注释类:

① 声明一个可重复注释类型:import java.lang.annotation.Repeatable;@Repeatable(Schedules.class)@interface Schedule{ String dayOfMonth() default "first"; String dayOfWeek() default "Mon"; int hour() default "";}注:上述 Schedules.class 没有写错,并不是 Schedule ,Schedules 也是一个注释类,其内部有一个返回 Schedule 数组的方法;存储注释类:编译器会存储可重复注释类到@Repeatable()括号中的注释类;可以说这个类 Schedules 是容器,包含了 Schedule 数组;
② 声明Repeatable注释类的容器类:@interface Schedules{ Scedule[] value();}

你可能感兴趣的:(Java Annotation 注释类的 Retention 和重复注释)