Java注解
概述
- Java注解概念:Java提供了一种原程序中的元素关联任何信息和任何元数据的途径和方法。
Java中的常见注解
- Java中的常见注解:
- JDK自带注解 :@Override @Deprecated @Suppvisewarnings
- 常见第三方注解:
Spring: @Autowired @Service @Repository
Mybatis: @InsertProvider @UpdateProvider @Options
注解的分类
-
按照运行机制分:
- 源码注解:注解只在源码中存在,编译成.class文件就不存在了。
- 编译时注解:注解在源码和.class文件中都存在。(例如JDK注解:@Override、@Deprecated、@Suppvisewarnings)
- 运行时注解:在运行阶段还起作用,甚至会影响运行逻辑的注解。(例如:Spirng提供的@Autowired注解,程序运行时,把成员变量自动注入)
-
按照来源分类:
- 来自JDK的注解
- 来自第三方的注解
- 自定义注解
-
元注解:给注解进行注解
自定义注解
- 自定义注解的语法要求:
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Description { //使用关键字@interface定义注解
String desc(); //成员以无参无异常方式声明
String author();
int age() default 18; //用default为成员指定默认值
}
- 注解的成员类型包括:原始类型、String、Class、Annotation、Enumeration
- 如果注解只有一个成员,则成员名必须为 value(),在使用是可以省略成员名和赋值号(=)
- 注解可以没有成员,没有成员的注解成为标识注解
- 元注解
-
@Target({ElementType.METHOD,ElementType.TYPE})
声明自定义注解的作用域,参数有:CONSTRUCTOR(构造方法)、FIELD(字段声明)、LOCAL_VARIABLE(局部变量声明)、METHOD(方法声明)、PACKAGE(包声明)、PARAMETER(参数声明)、TYPE(类,接口) -
@Retention(RetentionPolicy.RUNTIME)
注解的生命周期,参数有SOURCE(只在源码中显示,编译时丢弃)、CLASS(编译时会记录到class中,运行时忽略)、RUNTIME(运行时存在,可以通过反射读取) -
@Inherited
表示该注解对class使用时,可以被其子类继承 -
@Documented
表示生成javadoc是会包含注解的信息 -
自定义注解的使用:
@<注解名>(<成员名1>=<成员值1>,<成员名1>=<成员值1>,...)
@Description(desc="I am eyeColor",author="Mooc boy,age=18)
public String eyeColor(){
return "red";
}
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Description{ //使用@intreface关键字定义注解
String desc(); //成员以无参无异常方式声明
String author();
int age() default 18;//可以用default为成员指定一个默认值
}
- 解析注解:通过反射获取类、函数或成员上的运行时注解信息,从而实现动态控制程序运行的逻辑。
//1.使用类加载器加载类
try {
Class c = Class.forName("com.ann.test.Child");
//2.找到类上的注解
boolean isExist = c.isAnnotationPresent(Description.class);
if(isExist){
//3.拿到注解实例
Description d = (Description)c.getAnnotation(Description.class);
System.out.println(d.value());
}
//4.找到方法上的注解
Method[] ms = c.getMethods();
for(Method m:ms){
boolean isMExist = m.isAnnotationPresent(Description.class);
if(isMExist){
Description d = m.getAnnotation(Description.class);
System.out.println(d.value());
}
}
//另外一种解析方法
for(Method m:ms){
Annotation[] as = m.getAnnotations();
for(Annotation a:as){
if(a instanceof Description){
Description d = (Description)a;
System.out.println(d.value());
}
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
注意:
- RetentionPolicy.RUNTIME时,才能获取到注解,SOURCE和CLASS都获取不到注解。
- @Inherited对implements不起作用,对extends起作用(只会继承类上面注解,而不会继承该类方法中的注解)。