Annotation, 也叫元数据, JDK1.5引入, 与类,接口,枚举属于同一层次。可以声明在包/类/字段/方法/局部变量/方法参数等前面, 用来对这些元素进行说明。本质其实就是一个Annotation接口。
元注解
用来注解其他注解的注解,称为元注解。
元注解一共有5个,分别是@Retention、@Target、@Document、@Inherited和@Repeatable。
@Retention
Retention英文意思有保留、保持的意思,它表示注解存在阶段是保留在源码、字节码还是运行期(JVM)。
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
}
public enum RetentionPolicy {
SOURCE, //保留到源码阶段
CLASS, //保留到字节码阶段
RUNTIME //保留到JVM运行阶段
}
@Target
Target的英文意思是目标,这也很容易理解,使用@Target元注解表示我们的注解作用的范围就比较具体了,可以是类,方法,方法参数变量等,同样也是通过枚举类ElementType表达作用类型。
@Target(ElementType.TYPE)
public @interface MyAnnotation {
}
public enum ElementType {
TYPE, //作用接口、类、枚举、注解
FIELD, //作用属性字段、枚举的常量
METHOD, //作用方法
PARAMETER, //作用方法参数
CONSTRUCTOR, //作用构造函数
LOCAL_VARIABLE, //作用局部变量
ANNOTATION_TYPE, //作用于注解
PACKAGE, //作用于包
TYPE_PARAMETER, //作用于类型泛型,即泛型方法、泛型类、泛型接口 (jdk1.8加入)
TYPE_USE //类型使用.可以用于标注任意类型除了 class (jdk1.8加入)
}
@Document
它的作用是能够将注解中的元素包含到Javadoc中去
@Documented
public @interface MyAnnotation {
}
@Inherited
Inherited的英文意思是继承,但是这个继承和我们平时理解的继承大同小异,一个被@Inherited注解了的注解修饰了一个父类,如果他的子类没有被其他注解修饰,则它的子类也继承了父类的注解。
@Inherited
public @interface MyAnnotation {
}
@Repeatable
Repeatable的英文意思是可重复的。顾名思义说明被这个元注解修饰的注解可以同时作用一个对象多次,但是每次作用注解又可以代表不同的含义。
@Repeatable(User.class)
public @interface MyAnnotation {
}
class User implements Annotation {
@Override
public Class<? extends Annotation> annotationType() {
return null;
}
}
mybais中@Param注解的使用分析
@Param
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface Param {
String value();
}
使用@Param
class User {
//省略....
}
interface UserMapper {
User findById(@Param("id") Integer id);
}
mybatis框架解析@Param注解
class UserMapperParser {
public static void main(String[] args) throws NoSuchMethodException {
//1.获取UserMapper的Class对象
Class<UserMapper> clazz = UserMapper.class;
//2.获取findById方法
Method method = clazz.getDeclaredMethod("findById", Integer.class);
//3.解析findById方法
parseParams(method);
}
private static void parseParams(Method method) {
//获取方法参数个数
Class<?>[] parameterTypes = method.getParameterTypes();
int paramCount = parameterTypes.length;
//获取方法参数注解
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
//获取参数注解的value值
for(int paramIndex=0; paramIndex<paramCount; paramIndex++){
for (Annotation annotation: parameterAnnotations[paramIndex]){
if (annotation instanceof Param){
String value = ((Param) annotation).value();
System.out.println("value = " + value);
}
}
}
}
}