Java注解用途是配合反射设计框架使用
1、Annotation 概述
Java 代码中类上、构造器上、参数上、成员变量上和方法上等位置上的特殊标记,让程序根据注解信息决定如何运行代码。常见有@Override、@Test。
原理:
- 注解的本质是一个接口,Java 所有注解都继承了 Annotation 接口。
- @注解(…):其实就是一个实现类对象,实现了该注解及 Annotation 接口。
2、自定义注解
代码格式:
public @interface 注解名称 {
public 属性类型 属性名() (default 默认值);
}
栗子:
自定义注解:
public @interface MyTest1 {
String aa();
boolean bb() default true;
int[] cc();
}
使用自定义注解:
@MyTest1(aa="hahah", bb=false, cc={3,5})
public class AnnotationTest1 {
@MyTest1(cc={4}, aa="blbl")
int name;
@MyTest1(aa="cici", cc={0})
public void myMethod() {}
}
3、元注解
修饰注解的注解
栗子:
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest1 {
String aa();
boolean bb() default true;
int[] cc();
}
4、注解的解析
注解的解析就是判断 Java 代码中类上、成员变量上和方法上等位置上是否存在注解,并将其注解的内容解析出来。
步骤:比如要解析类上的注解,则应先获取该类的 Class 对象,再通过 Class 对象解析其上面注解。
Class、Field、Method、Constructor都实现了 AnnotationElement 接口,它们都具备有解析注解的能力。
栗子:
创建一个类上、成员变量上和方法上含有注解的代码:
@MyTest1(aa="hahah", bb=false, cc={3,5})
public class AnnotationTest1 {
@MyTest1(cc={4}, aa="blbl")
int name;
@MyTest1(aa="cici", cc={0})
public void myMethod() {}
@MyTest1(aa="", cc={})
public void test1() {
System.out.println("------test1------");
}
// @MyTest1(aa="", cc={})
public void test2() {
System.out.println("------test2------");
}
@MyTest1(aa="", cc={})
public void test3() {
System.out.println("------test3------");
}
}
解析类上和成员方法上的注解:
public class AnnotationTest2 {
@Test
// 解析类上注解
public void parseClass() {
// 1.获取 Class 对象
Class c = AnnotationTest1.class;
// 2、判断类上是否有某个注解
if (c.isAnnotationPresent(MyTest1.class)) {
// 3.获取指定注解对象
MyTest1 myTest1 = (MyTest1) c.getDeclaredAnnotation(MyTest1.class);
// 4.解析注解内容
System.out.println(myTest1.aa());
System.out.println(myTest1.bb());
System.out.println(Arrays.toString(myTest1.cc()));
}
}
@Test
// 解析方法上注解
public void parseMethod() throws Exception {
// 1、获取 Class 对象
Class c = AnnotationTest1.class;
// 2.获取类中指定方法 Method 对象
Method myMethod = c.getDeclaredMethod("myMethod");
// 3.判断类中方法上是否有某个注解
if (myMethod.isAnnotationPresent(MyTest1.class)) {
// 4.获取指定注解对象
MyTest1 myTest1 = myMethod.getDeclaredAnnotation(MyTest1.class);
// 5.解析注解内容
System.out.println(myTest1.aa());
System.out.println(myTest1.bb());
System.out.println(Arrays.toString(myTest1.cc()));
}
}
}
5、应用场景
编写一个类似于 @Test 注解功能的程序,让类中含有 @MyTest1 注解的方法执行方法中的程序。
public class AnnotationTest3 {
@Test
// 让类中方法上有注解的方法执行方法中代码
public void testMyTest() throws Exception {
AnnotationTest1 annotationTest1 = new AnnotationTest1();
// 1.获取 Class 对象
Class c = AnnotationTest1.class;
// 2.获取类中方法 Method 对象,以数组形式进行存储
Method[] methods = c.getDeclaredMethods();
// 3.遍历数组,获取每个 Method 对象
for (Method method : methods) {
// 4.判断类中方法上是否存在注解
if (method.isAnnotationPresent(MyTest1.class)) {
// 执行存在注解方法
method.invoke(annotationTest1);
}
}
}
}