注解是什么
注释是绑定到程序源代码元素的元数据,对它们运行的代码的操作没有影响。
https://blog.csdn.net/SDDDLLL/article/details/93509699
他们的典型用例是:
编译器的信息 - 使用注释,编译器可以检测错误或抑制警告
编译时和部署时处理 - 软件工具可以处理注释并生成代码,配置文件等。
运行时处理 - 可以在运行时检查注释以自定义程序的行为
Java的注解可以分为三类:
第一类是由编译器使用的注解,例如:
@Override - 检查该方法是否是重载方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。
@Deprecated - 标记过时方法。如果使用该方法,会报编译警告。
@SuppressWarnings - 指示编译器去忽略注解中声明的警告。
这类注解不会被编译进入.class文件,它们在编译后就被编译器扔掉了。
第二类是由工具处理.class文件使用的注解,比如有些工具会在加载class的时候,对class做动态修改,实现一些特殊的功能。这类注解会被编译进入.class文件,但加载结束后并不会存在于内存中。这类注解只被一些底层库使用,一般我们不必自己处理。
泛型
实际上ArrayList内部就是一个Object[]数组,
泛型类似C++模板
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
extends 和
Pair<? extends Number>使得方法接收所有泛型类型为Number或Number子类的Pair类型。我们把代码改写如下:
Pair<? super Integer>表示,方法参数接受所有泛型类型为Integer或Integer父类的Pair类型。
泛型与反射关系
https://blog.csdn.net/hivon/article/details/1328152
第三类是在程序运行期能够读取的注解,它们在加载后一直存在于JVM中,这也是最常用的注解。例如,一个配置了@PostConstruct的方法会在调用构造方法后自动被调用(这是Java代码读取该注解实现的功能,JVM并不会识别该注解)。
定义一个注解时,还可以定义配置参数。配置参数可以包括:
所有基本类型;
String;
枚举类型;
基本类型、String以及枚举的数组。
因为配置参数必须是常量,所以,上述限制保证了注解在定义时就已经确定了每个参数的值。
注解的配置参数可以有默认值,缺少某个配置参数时将使用默认值。
定义注解
Java语言使用@interface语法(其中关键字接口以@开头)来定义注解(Annotation),它的格式如下:
public @interface Report {
int type() default 0;
String level() default "info";
String value() default "";
}
元注解
@Retention - 标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可以通过反射访问。
@Documented - 标记这些注解是否包含在用户文档中。
@Target - 标记这个注解应该是哪种 Java 成员。
@Inherited - 标记这个注解是继承于哪个注解类(默认 注解并没有继承于任何子类)
java7新增
@SafeVarargs - Java 7 开始支持,忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告。
@FunctionalInterface - Java 8 开始支持,标识一个匿名函数或函数式接口。
@Repeatable - Java 8 开始支持,标识某注解可以在同一个声明上使用多次。