public class User {
public void show(){
System.out.println("hello world!");
}
}
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Prop {
String className();
String methodName();
}
/**
* 框架类
* 前提:不能改变该类的任何代码。可以创建任意类的对象,可以执行任意方法
*/
@Prop(className = "com.scu.annotation.User",methodName = "show")
public class PropTest {
public static void main(String[] args) throws Exception {
//1.解析注解
//1.1获取该类的字节码文件对象
Class<PropTest> clazz = PropTest.class;
//2.获取上边的注解对象
//其实就是在内存中生成了一个该注解接口的子类实现对象
/*
public class ProImpl implements Pro{
public String className(){
return "com.scu.annotation.User";
}
public String methodName(){
return "show";
}
}
*/
Prop annotation = clazz.getAnnotation(Prop.class);
//3.调用注解对象中定义的抽象方法,获取返回值
String className = annotation.className();
String methodName = annotation.methodName();
//3.加载该类进内存
Class cls = Class.forName(className);
//4.创建对象
Object instance = cls.newInstance();
//5.获取方法对象
Method method = cls.getMethod(methodName);
//6.执行方法
method.invoke(instance);
}
}
//运行后输出 "hello world!"
@Target:描述注解能够作用的位置
ElementType取值:
TYPE:可以作用于类上
METHOD:可以作用于方法上
FIELD:可以作用于成员变量上
@Retention:描述注解被保留的阶段 三个阶段
@Retention(RetentionPolicy.RUNTIME):当前被描述的注解,会保留到class字节码文件中,并被JVM读取到 如果是CLASS则也会保留到字节码文件中但是不会被jvm读取到 SOURCE则都不可以 (Override就是SOURCE这个阶段)
@Documented:描述注解是否被抽取到api文档中 使用javadoc生成后能够看到
@Inherited:描述注解是否被子类继承
对于Target,来看源码中仅有的一个属性value:
ElementType[] value();
ElementType枚举中的类型主要是TYPE,METHOD,FIELD。