简介
自定义注解
定义
// 自定义注解
public @interface MyAnnotation {
// 注解的属性
// value是注解的一个属性,如果只有一个属性,建议使用value
String value() default "";
boolean enabled() default true;
String[] exclude() default {};
}
使用
// 使用自定义注解
@MyAnnotation(value = "hello", enabled = false, exclude = {"a", "b"})
public class TestMyAnnotation {
// 如果注解中只有一个属性,且属性名为value,那么在使用时可以省略属性名
@MyAnnotation("world")
public static void main(String[] args) {
}
}
注解原理
借助反编译工具
元注解
元注解:修饰注解的注解
位置
被修饰的位置是一个
枚举类
@Target({ElementType.TYPE,ElementType.METHOD}) // 多个位置之间用逗号隔开
public @interface MyAnnotation2 {
}
保留周期
- 常用的是第三种:一直保留下来
@Retention(RetentionPolicy.RUNTIME) // 运行时
public @interface MyAnnotation2 {
}
注解的解析
案例
注解MyTest4
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest4 {
String value() default "";
double aaa() default 100;
String[] bbb() default {"a", "b", "c"};
}
Demo类
- 分别在类和方法上定义注解
@MyTest4(value = "Demo", aaa = 100, bbb = {"a", "b", "c"})
public class Demo {
@MyTest4(value = "test1", aaa = 200, bbb = {"a", "c"})
public void test1() {
System.out.println("Hello world!");
}
}
测试类:用来解析注解
- 解析注解的第一部永远都是
先获取被解析的对象
应用场景:模拟Junit框架
注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest {
}
模拟Junit框架
- 因为没有官方进行框架整合,我们使用main方法进行模拟
public class AnnotationTest4 {
@MyTest
public void test1(){
System.out.println("--test1---");
}
public void test2(){
System.out.println("--test2---");
}
@MyTest
public void test3(){
System.out.println("--test3---");
}
// 使用main方法模拟启动按钮
public static void main(String[] args) {
//1. 获取当前类的字节码对象
Class<AnnotationTest4> annotationTest4Class = AnnotationTest4.class;
//2. 获取当前类的所有方法
Method[] declaredMethods = annotationTest4Class.getDeclaredMethods();
//3. 遍历所有方法
for (Method declaredMethod : declaredMethods) {
//4. 判断方法上是否有MyTest注解
if (declaredMethod.isAnnotationPresent(MyTest.class)) {
System.out.println(declaredMethod.getName() + "方法上有MyTest注解");
// 5. 执行有MyTest注解的方法
try {
declaredMethod.invoke(annotationTest4Class.newInstance());
} catch (Exception e) {
e.printStackTrace();
}
} else {
System.out.println(declaredMethod.getName() + "方法上没有MyTest注解");
}
}
}
}