- 注解的本质是接口
- 注解可以用于替换配置文件的功能
- 注解中的属性即接口的抽象方法
元注解
- 注解的注解,定义注解的范围,ElementType.TYPE(类),ElementType.METHOD(方法),ElementType.FIELD(成员变量)
- 定义持续时间@Retention(RetentionPolicy.RUNTIME)(运行时)
- 继承
- javadoc
注解中属性类型
- 返回值不能有类类型
package annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(value = {ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
public @interface MyAnno {
int age();
String name() default "zhangsan";
Person per();
MyAnno2 anno2();
String[] strs();
}
自定义注解Pro
package annotation;
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();
String methodName();
}
反射类
package annotation;
import java.lang.reflect.Method;
@Pro(className = "annotation.Demo1", methodName = "show")
public class ReflectTest {
public static void main(String[] args) throws Exception {
//解析注解,获取字节码对象文件
Class<ReflectTest> reflectTestClass = ReflectTest.class;
//获取上边的注解对象
//其实就是在内存中生成了一个该注解接口的子类实现对象
Pro an = reflectTestClass.getAnnotation(Pro.class);
String className = an.className();
//获取配置文件中定义的数据
System.out.println("className = " + className);
String methodName = an.methodName();
System.out.println("methodName = " + methodName);
//加载该类进内存
Class cls = Class.forName(className);
//创建对象
Object obj = cls.newInstance();
//获取方法对象
Method method = cls.getMethod(methodName);
//执行方法
method.invoke(obj);
}
}
被反射的类
package annotation;
public class Demo1 {
public void show(){
System.out.println("show1....");
}
}