本笔记来源慕课网视频:http://www.imooc.com/learn/456
1. Java中常见注解
@Override: 覆盖父类方法
@Deprecated: 标记已过时的方法
@SuppressWarnings: 忽略警告,如@SuppressWarnings ( “ deprecation ” ) ,忽略过时方法的警告
2. 注解的分类
(1)按照来源分类:
①来自JDK的注解;②来自第三方的注解(如:Spring, Struct , Hibenate等基于注解的DI);③自定义注解
(2)按照注解的作用域分类:
①普通注解:只能注解类、字段、方法、参数、包和接口的注解
②元注解:注解的注解,包括:@Target(ElementType),@Retention(RetentionPolicy), @Documented, @Inherited
(3)按照运行机制分类:
①源码注解[SOURCE];②编译时注解[CLASS];③运行时注解[RUNTIME]
3.自定义注解—语法要求
(1)使用 @interface 定义注解。如:
public @interfaceDescription
(2)注解类可以没有成员,没有成员的注解称为标识注解
(3)成员类型是受限的,成员类型只能是byte, short,char, int, long, float, double, boolean 这八种基本类型和String, Class,Annotation, Enumeration 和 1维数组,成员名后面需加 “()”。如:
String desc();
当注释内只有一个成员时,其字段名可谓value,这样在调用时无需写成员名和赋值号(“=”)
(4)成员需以无参数无异常的方式声明
(5)注释的调用
①所有的成员都必须被赋值,或者默认值,可用 default 关键字设置默认值,如:
String author() default"admin";
②注释调用的格式:
@<注释名>(<成员名1>=<成员值1>, <成员名2>=<成员值2>, … <成员名n>=<成员值n>),如:
@Description(desc="ClassPerson -- This is Class Annotation", author="user")
4.自定义注解的注解(元注解的意义)
(1) @Target :必须。此注解描述了自定义注解的使用环境。其枚举类型(ElementType)包括:①注释类型声明(ANNOTATION_TYPE);②构造方法声明(CONSTRUCTOR)③字段声明(FIELD)④局部变量声明(LOCAL_VARIABLE)⑤方法声明(METHOD)⑥包声明(PACKAGE)⑦参数声明(PARAMETER)⑧类、接口或枚举声明(TYPE)
(2)@Retention :必须。此注解描述了自定义注解的运行机制。其类型(RetentionPolicy)有:
①注解只在源码中存在(SOURCE),编译成 .class 文件就不存在了。
②注解在源码和编译时存在(CLASS),注解在源码和 .class 文件中都存在。
③注解在源码,编译和运行时存在(RUNTIME),注解在运行阶段还起作用,甚至会影响运行逻辑的注解。
比如,Java常用注解中的 @Override和@SuppressWarnings是只在源码的注解,@Deprecated是运行时注解。
(3)@Inherited :非必须。此注解允许自定义注解被子类继承。即当此自定义注解注解了一个父类或方法时,子类在继承父类或父类的方法时,也会将这个自定义注解继承过来。注意:在实现一个接口时并不会继承此自定义注解,在子类中重写了父类的方法时也不会继承此自定义注解。
(4)@Documented :非必须。此注解主要用于生成JavaDoc时包含此注解信息。
5.解析注解
通过反射获取类、函数或成员上的运行时注解信息,从而实现动态控制程序运行的逻辑,步骤如下:
(1)使用类加载器加载类[Class.forName() 或 Object.class或 object.getClass()]
(2)找到类上的注解[object.isAnnotationPresent()]
(3)获取注解实例[object.getAnnotation()]
(4)找到方法上的注解:有两种方法
①遍历类的所有方法[class.getMethods()];找到方法上的注解[isAnnotationPresent()];获取注解实例[getAnnotation()]
②遍历类的所有方法[class.getMethods()];遍历注解[getAnnotations];实例判断[instanceof]
建议使用法①,这样可以减少遍历的次数,提高程序运行效率。
注意:需要解析的自定义注解的运行机制(RetentionPolicy)必须要为运行时(RUNTIME)
(5)调用方法[method.invoke(object,parameters)]