注解
概述、自定义注解
-
注解是指Java代码中的特殊标记,比如:@Override、@Test等,作用是:让其他程序根据注解信息来决定怎么执行该程序
-
自定义注解就是自己定义注解
-
public @interface MyFirstAnnotation { int age() default 0; String name(); } public @interface MySecondAnnotation { String value(); //特殊属性,使用时可以不用写 value = } @MyFirstAnnotation(age = 18, name = "zxx") @MySecondAnnotation("as") public class TestAnnotation { }
-
自定义注解的本质是一个继承了Annotation的接口,接口中定义抽象方法作为注解的属性,当我们使用注解时,相当于实例化了一个对象
元注解
- 指的是修饰注解的注解
- @Target :声明被修饰的注解可以在哪些位置使用,在ElementType枚举类中定义了各种位置
- @Retention:声明注解的保留周期,在RetentionPolicy枚举类中定义了三种周期
注解的解析
-
判断类上面、方法上面、成员变量上是否存在注解,并把注解里的内容给解析出来
-
解析谁上面的注解,就要先获得谁的Class对象
-
Class、Method、Field、Constructor都实现了AnnotationedElement接口,他们都拥有解析注解的能力
-
AnnotationedElement接口提供了解析注解的方法 说明 public Annotation[] getDeclaredAnnotations() 获取当前对象上面的注解 public T getDeclaredAnnotation(Class annotationClass) 获取指定的注解对象 public boolean isAnnotationPresent(Class annotationClass) 判断当前对象上是否存在某个注解 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface MyTestAnnotation { String value(); double aaa() default 100; String[] bbb(); }
import java.lang.reflect.Method; import java.util.Arrays; @MyTestAnnotation(value = "zxx", aaa = 18, bbb = {"zxx", "hhh"}) public class Demo { @MyTestAnnotation(value = "hhh", aaa = 15, bbb = {"hhh", "zxx"}) public void test1() { } public static void main(String[] args) throws NoSuchMethodException { // 1.先得到Class对象 Class c1 = Demo.class; // 2.获取当前对象上的注解 if (c1.isAnnotationPresent(MyTestAnnotation.class)) { MyTestAnnotation myTestAnnotation = (MyTestAnnotation) c1.getDeclaredAnnotation(MyTestAnnotation.class); System.out.println(myTestAnnotation.value()); System.out.println(myTestAnnotation.aaa()); System.out.println(Arrays.toString(myTestAnnotation.bbb())); } Method method = c1.getMethod("test1"); if (method.isAnnotationPresent(MyTestAnnotation.class)) { MyTestAnnotation myTestAnnotation = (MyTestAnnotation) method.getDeclaredAnnotation(MyTestAnnotation.class); System.out.println(myTestAnnotation.value()); System.out.println(myTestAnnotation.aaa()); System.out.println(Arrays.toString(myTestAnnotation.bbb())); } } }
应用场景
-
需求:定义了若干个方法,只要加了MyTest注解,就会触发该方法执行
-
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface MyTest { }
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class JunitTest { @MyTest public void test1() { System.out.println("我是test1"); } @MyTest public void test2() { System.out.println("我是test2"); } public void test3() { System.out.println("我是test3"); } @MyTest public void test4() { System.out.println("我是test4"); } public static void main(String[] args) throws InvocationTargetException, IllegalAccessException { Class c1 = JunitTest.class; Method[] methods = c1.getDeclaredMethods(); for (Method method : methods) { if (method.isAnnotationPresent(MyTest.class)) { method.setAccessible(true); method.invoke(new JunitTest()); } } } }