注解简介
注解,可以看作是对一个类/方法的一个扩展的模版,每个类/方法按照注解类中的规则,来为类/方法注解不同的参数,在用到的地方可以得到不同的类/方法中注解的各种参数与值。
从JDK5开始,java增加了对元数据(描述数据属性的信息)的支持。其实说白就是代码里的特殊标志,这些标志可以在编译,类加载,运行时被读取,并执行相应的处理,以便于其他工具补充信息或者进行部署。n
基本注解
java提供了5个基本的注解,分别是
1.@Override
2.@Deprecated
3.@SuppressWarnings
4.@SafeVarargs
5.@FunctionalInterface
限定父类重写方法:@Override
当子类重写父类方法时,子类可以加上这个注解,那这有什么什么用?这可以确保子类确实重写了父类的方法,避免出现低级错误n
标示已过时:@Deprecated
这个注解用于表示某个程序元素类,方法等已过时,当其他程序使用已过时的类,方法时编译器会给出警告(删除线,这个见了不少了吧)。n
抑制编译器警告:@SuppressWarnings
被该注解修饰的元素以及该元素的所有子元素取消显示编译器警告,例如修饰一个类,那他的字段,方法都是显示警告n
“堆污染”警告与@SafeVarargs
想理解这个就要明白什么是堆污染,堆污染是什么?
其实很好理解,就是把不带泛型的对象赋给一个带泛型的对象,为什么不行?很简单,因为不带泛型的话,默认会给泛型设定为object,意思就是什么类型都可以往里面塞,那你一个不带泛型的怎么可能给一个带泛型塞呢。
注意:可变参数更容易引发堆污染异常,因为java不允许创建泛型数组,可变参数恰恰是数组。
抑制这个警告的方法有三个:1.@SafeVarargs修饰引发该警告的方法或构造器2.使用@suppressWarnings("unchecked")3.编译时使用-Xlint:varargs
函数式接口与@Functionallnterface
什么是函数式?如果接口中只有一个抽象方法(可以包含多个默认方法或多个static方法)
接口体内只能声明常量字段和抽象方法,并且被隐式声明为public,static,final。
接口里面不能有私有的方法或变量。
这个注解有什么用?这个注解保证这个接口只有一个抽象方法,注意这个只能修饰接口n
方法信息
equals boolean equals(Object obj)如果指定的对象表示在逻辑上等效于此接口的注释,则返回true。换句话说,如果指定对象是一个与此实例相同的annotation类型的实例,即其所有成员都与此实例中所对应的成员相等,则返回true,具体说明如下:
如果x==y,则认为值分别为x和y的两个对应的基本类型成员相等,除非它们的类型是float或double。
如果Float.valueOf(x).equals(Float.valueOf(y))为真,则认为值分别为x和y的两个对应的float成员相等。(与==运算符不同,NaN被认为等于其自身,并且0.0f不等于-0.0f。)
如果Double.valueOf(x).equals(Double.valueOf(y))为真,则认为值分别为x和y的两个对应的double成员相等。(与==运算符不同,NaN被认为等于其自身,并且0.0不等于-0.0。)
如果x.equals(y)为真,则认为值分别为x和y的两个对应的String、Class、enum或annotation类型的成员相等。(注意,此定义对于annotation类型的成员是递归的。)
对于适当重载的Arrays.equals(long[],long[]),如果Arrays.equals(x,y)为真,则认为两个对应的数组类型的成员x和y相等。
处理器
通过annotation processing tool(注释处理工具,简称apt),可以处理源码中的注释,获得更灵活的代码,也将程序员从样板式的编程中解放了出来。
为了使注释(annotation)中的信息能在运行时(RUNTIME)被程序利用,在创建注释时,应该给注释的类名添加@Retention(RetentionPolicy.RUNTIME)注释。
构建自定义注释信息处理器与以下API有关:
Mirror API(已过时Deprecated)
javax.annotation.processing
javax.lang.model
javax.lang.model.element
javax.lang.model.type
javax.lang.model.util