元注解:用于描述注解的注解
* @Target:描述注解能够作用的位置
* ElementType【是一个枚举】取值:
* TYPE:可以作用于类上
* METHOD:可以作用于方法上
* FIELD:可以作用于成员变量上
* @Retention:描述注解被保留的阶段【Java代码有三个阶段:源代码阶段-》class类对象阶段-》Runntime运行阶段】
* @Retention(RetentionPolicy.RUNTIME):当前被描述的注解,会保留到class字节码文件中,并被JVM读取到【主要】
//没有Retention注解时,默认使用class注解,但在运行时不会被JVM保留。
* @Documented:描述注解是否被抽取到api文档中,加上后注解则会将被抽取到api文档中
* @Inherited:描述注解是否被子类继承。子类会自动继承父类的注解
自定义注解时,属性的返回值只能为下列值:
* 基本数据类型
* String
* 枚举
* 注解
* 以上类型的数组
题型示例:
自定义注解Pro:
@Target(ElementType.TYPE) //@Retention(RetentionPolicy.RUNTIME):当前被描述的注解,会保留到class字节码文件中,并被JVM读取到【主要】 //没有retention注解时,默认使用class注解,但在运行时不会被JVM保留。 @Retention(RetentionPolicy.RUNTIME) public @interface Pro { String className(); String methodName(); }
自定义demo方法:
public class Demo01 { public void sleep(){ System.out.println("睡,,,"); } }
自定义类ReflectDemo:
//引用注解 @Pro(className = "cn.itma.annotationFrame.Demo01", methodName = "sleep") public class ReflectDemo { public static void main(String[] args) throws Exception { //需要带上泛型 //获取该类的字节码文件对象 Class<ReflectDemo> clazz = ReflectDemo.class; // Class clazz = ReflectDemo.class; //不加泛型,则会返回注解类的超类 // Annotation annotation1 = clazz.getAnnotation(Pro.class); // annotation1.className(); className方法不会被调用 Pro annotation = clazz.getAnnotation(Pro.class); System.out.println(annotation); //调用注解对象中的定义的抽象方法,获取返回值 String className = annotation.className(); String methodName = annotation.methodName(); //加载该类进内存 Class<?> aClass = Class.forName(className); //创建该类的对象 Object newInstance = aClass.newInstance(); //获取该对象的方法 Method method = aClass.getMethod(methodName); //激活该方法 method.invoke(newInstance); } }