Annotation注解
注解概述
通俗来说,注解和之前接触的注释都是用来说明程序的,但注解是给计算机看的
注解本质上是一个接口
是代码中的特殊标记,可用于标记类、接口、构造器、成员方法、变量等
注解的分类
按作用分
- 编写文档:通过代码里标识的注解生成文档
- 代码分析:通过代码里标识的注解对代码进行分析
- 编译检查:通过代码里标识的注解让编译器能实现基本的编译检查
按是否有成员变量分
- 标记注解:不包含成员变量,它的存在知识提供信息
- 元数据注解:包含成员变量,可以接收元数据
JDK内置注解
- @Override:(标记注解)强制重写父类的方法,通常标记方法,作用在于告诉编译器检测该方法,保证其父类存在一个被该方法覆写的方法
- @Deprecated:用于表示被标记的程序元素已过时
- @SuppressWarnings:压制警告信息
元注解
概念:用于修饰注解的注解,即修饰注解定义
- @Target:指定该注解用于修饰哪些程序元素
@Target({ElementType.TYPE}) //注解作用在类、接口上
@Target({ElementType.METHOD}) //注解作用在方法
@Target({ElementType.FIELD}) //注解作用在成员变量
@Target({ElementType.LOCAL_VARIABLE}) //注解作用在局部变量
- @Retention:指定注解的保留时期
@Retention(RetentionPolicy.RUNTIME) //运行时,JVM可以获取注解信息
@Retention(RetentionPolicy.SOURCE) //源码中,编译器丢弃
@Retention(RetentionPolicy.CLASS) //保存在class文件中,JVM不可获取信息
- @Documented:被其修饰的注解会被抽取到文档中
- @Inherited:被其修饰的注解具有继承性
自定义注解
格式:
元注解
public @interface 注解名称{
成员变量(用抽象方法表示);
}
属性:接口中可以定义的成员方法
要求:
1>.属性的返回值类型可以是一下几种
基本数据类型
String
枚举类型
注解类型
以上类型的数组
2>.定义了属性,在使用的时候需要给属性赋值
可以在定义注解的时候,使用default关键字对属性设置初始值,使用时,可赋值也可以不赋值
如果使用注解时,只需要为value成员变量指定值,那么value可以省略
数组赋值的时候,使用{}包裹,只有一个数组元素的时候{}可以省略
在程序中使用注解
- 获取注解定义位置的对象
- 获取指定的注解
getAnnotation(注解.class)
- 调用注解的抽象方法获取配置的属性值
import java.lang.reflect.Method;
@Pro(className = "cs.itcode.annotation.Student",methodName = "show")
public class Annotation_02_Test {
public static void main(String[] args) throws Exception {
//不改动该类的代码,创建任意类的对象,执行任意的方法
//1.获取注解定义位置的对象
Class<Annotation_02_Test> cls = Annotation_02_Test.class;
//2.获取指定的注解
//下面的代码本质上实在内存中生成了1个该注解的实现类对象
Pro pro = cls.getAnnotation(Pro.class);
//3.调用注解的抽象方法获取配置的属性值
String className = pro.className();
String methodName = pro.methodName();
Class<?> cls1 = Class.forName(className);
Object o = cls1.newInstance();
Method method = cls1.getMethod(methodName);
method.invoke(o);
}
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 描述需要执行的类名和方法名
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Pro {
String className();
public abstract String methodName();
}
重复注解
Java8之前,如果需要同一个元素前使用多个相同类型的注解,必须使用注解“容器”;从Java8开始,允许使用多个相同类型的注解来修饰同一个类
@Result(name = "fail", location = "fail.jsp")
@Result(name = "success", location = "success.jsp")
public class Anno{
}
开发重复注解使用@Repeatable修饰,如下
“容器”注解的保留期必须比它包含的注解保留期长,否则编译出错
//定义可重复注解
@Repeatable(Annos.class)
@interface Anno{}
@Retention(value = RetentionPolicy.RUNTIME)
@interface Annos{
Anno[] value();
}