注解概念
注释:用文字描述程序,给程序员看
注解:也叫元数据,jdk1,5以后的新特性,用于说明程序。
使用注解:@注解名称
作用分类
- 编写文档 javadoc 类名.java
- 代码分析:通过代码里标识的注解对代码进行分析【使用反射】
- 编译检查:通过代码里标识的注解让编译器能够实现基本编译检查【override】
JDK预定义一些注解
@override:检测被该注解标注的方法是否继承自父类(接口)的
标示已过时:@Deprecated
抑制编译器警告:@SuppressWarnings:一般传递参数(“all”)
自定义注解
格式:
元注解
public @interface 名称
注解本质 public interface MyAnno extends java.lang.annotation.Annotation{}
注解本质就是一个接口,该接口默认继承Annotation接口
属性:接口可以定义的成员方法
- 属性的返回值类型,除以下其他都不行
string
基本数据类型
枚举类型
注解
以上类型的数组
- 定义了属性在使用时需要进行赋值
如果定义属性时,用default关键字给属性默认初始化值,使用注解可以不进行属性赋值
如果只有一个属性需要赋值,并且属性名称是value,则value可以省略直接写值即可
数组赋值时,值使用{}包裹,如果数组只有一个值,则{}省略
元注解
描述注解的注解
- @Target
描述注解作用的位置
取值 注解使用范围
METHOD 可用于方法上
TYPE 可用于类或者接口上
ANNOTATION_TYPE 可用于注解类型上(被@interface修饰的类型)
CONSTRUCTOR 可用于构造方法上
FIELD 可用于域上
LOCAL_VARIABLE 可用于局部变量上
PACKAGE 用于记录java文件的package信息
PARAMETER 可用于参数上
- @Retention
描述注解被保留的阶段
value的值有且仅有三个:
RetenionPolicy.CLASS 编译器把该注解记录在class文件中。当运行java程序时,JVM不可获取注解信息。这是默认值!
RetenionPolicy.RUNTIME编译器把该注解记录在class文件中。当运行java程序时,JVM可获取注解信息,程序可以通过反射获取该注解信息
RetenionPolicy.SOURCE 该注解只保存在源代码中,编译器直接丢弃该注解
- @Documented
这个注解用于指定被修饰的注解类将被javadoc工具提取成文档,如果定义注解类时使用了这个注解修饰,则所有使用该注解修饰的程序员苏API文档将会包含该注解说明。
例如:@Documented public @interface Testable{} - @Inherited
这个注解指定被他修饰的注解将具有继承性——如果某个类使用了@Xxx,则其子类将自动被@Xxx修饰
注解实现框架
@Pro(className = "day01.Person",methodName = "eat")
public class AnnotationReflect {
public static void main(String[] args) throws Exception {
//1. 获取该类的字节码文件
Class<AnnotationReflect> ar = AnnotationReflect.class;
//2. 获取上边的注解对象
Pro annotation = ar.getAnnotation(Pro.class);
//3. 调用注解对象定义的抽象方法,获取返回值
String className = annotation.className();
String methodName = annotation.methodName();
//4.把字节码文件加载到内存中
Class cl = Class.forName(className);
//5. 构造对象
Object obj = cl.newInstance();
Method method = cl.getMethod(methodName);
method.invoke(obj);
}