Java基础—解析注解
目录
案例要求:
实现思路:
代码:
MyTest4类:
Demo类:
AnnotationTest3类:
总结:
案例要求:
实现思路:
代码:
MyTest4类:
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 MyTest4 {String value() ;double aaa() default 100;String[] bbb();
}
这是一个 Java 自定义注解(Annotation)MyTest4
,用于在代码中添加元数据(描述数据的数据),可以标记在类、方法上,在运行时被程序读取和使用。
注解的核心组成
-
注解声明
public @interface MyTest4
表示定义一个名为MyTest4
的注解(注解),这是 Java 注解的固定语法。 -
元注解(注解的注解)
用于限定MyTest4
的使用范围和生命周期:-
@Target({ElementType.TYPE, ElementType.METHOD})
规定MyTest4
可以标记的位置:ElementType.TYPE
:允许标记在类、接口、枚举上ElementType.METHOD
:允许标记在方法上
-
@Retention(RetentionPolicy.RUNTIME)
规定MyTest4
的生命周期:RetentionPolicy.RUNTIME
表示注解在程序运行时仍然存在,可通过反射获取(最常用的生命周期)。
-
-
注解的属性
类似类的成员变量,用于存储注解的具体信息:String value()
:无默认值的字符串属性(特殊属性,使用时可省略属性名,直接写值)。double aaa() default 100
:带默认值的 double 类型属性(默认值 100)。String[] bbb()
:无默认值的字符串数组属性。
Demo类:
@MyTest4(value="欧阳娜娜",aaa = 666, bbb={"1","2"})
public class Demo {@MyTest4(value="宋小宝", bbb={"1","2"})public void test1(){}
}
这段代码展示了如何在实际类和方法上使用之前定义的自定义注解 @MyTest4
,通过为注解指定属性值,为类和方法添加了自定义元数据。
代码解析
-
类上的
@MyTest4
注解java
运行
@MyTest4(value="欧阳娜娜", aaa = 666, bbb={"1","2"}) public class Demo { ... }
- 为
Demo
类标记了@MyTest4
注解,并指定了三个属性的值:value = "欧阳娜娜"
:字符串属性,描述类的相关信息aaa = 666
:覆盖默认值(原本默认是 100),设置为 666bbb = {"1", "2"}
:字符串数组属性,包含两个元素 "1" 和 "2"
- 为
-
方法上的
@MyTest4
注解java
运行
@MyTest4(value="宋小宝", bbb={"1","2"}) public void test1(){ ... }
- 为
test1
方法标记了@MyTest4
注解,指定了两个属性:value = "宋小宝"
:描述方法的相关信息bbb = {"1", "2"}
:字符串数组属性(必须指定,因为注解定义中没有默认值)- 未指定
aaa
属性,将使用注解中定义的默认值 100
- 为
核心意义
这些注解本身不会直接影响程序的运行逻辑,而是作为元数据附加在类和方法上。通过反射机制,程序可以在运行时读取这些注解的属性值,实现自定义逻辑,例如:
- 框架可以根据注解标识的类 / 方法进行特殊处理(如自动注册、权限校验等)
- 测试工具可以识别标记了注解的方法并执行测试
- 代码生成工具可以根据注解信息自动生成相关代码
反射读取示例
如果用反射读取 Demo
类和 test1
方法上的注解信息,会得到如下结果:
java
运行
// 读取类上的注解
MyTest4 classAnnotation = Demo.class.getAnnotation(MyTest4.class);
System.out.println(classAnnotation.value()); // 输出:欧阳娜娜
System.out.println(classAnnotation.aaa()); // 输出:666.0
System.out.println(Arrays.toString(classAnnotation.bbb())); // 输出:[1, 2]// 读取方法上的注解
MyTest4 methodAnnotation = Demo.class.getMethod("test1").getAnnotation(MyTest4.class);
System.out.println(methodAnnotation.value()); // 输出:宋小宝
System.out.println(methodAnnotation.aaa()); // 输出:100.0(使用默认值)
System.out.println(Arrays.toString(methodAnnotation.bbb())); // 输出:[1, 2]
总结来说,这段代码是 @MyTest4
注解的实际应用,通过为类和方法添加注解属性,为程序提供了可在运行时解析的额外信息,是 Java 反射和注解机制结合的典型用法。
AnnotationTest3类:
import org.junit.Test;import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.Arrays;public class AnnotationTest3 {@Testpublic void parseClass() throws Exception{Class c1=Demo.class;if(c1.isAnnotationPresent(MyTest4.class)){MyTest4 myTest4=(MyTest4) c1.getAnnotation(MyTest4.class);String value=myTest4.value();double aaa=myTest4.aaa();String[] bbb=myTest4.bbb();System.out.println( value);System.out.println( aaa);System.out.println(Arrays.toString(bbb));}}@Testpublic void parseMethod() throws Exception{Class c1=Demo.class;Method methods=c1.getMethod("test1");if(methods.isAnnotationPresent(MyTest4.class)){MyTest4 myTest4= methods.getAnnotation(MyTest4.class);String value=myTest4.value();double aaa=myTest4.aaa();String[] bbb=myTest4.bbb();System.out.println( value);System.out.println( aaa);System.out.println(Arrays.toString(bbb));}}
}
这个 AnnotationTest3
类是一个测试类,用于通过 Java 反射机制 读取并解析 Demo
类及其方法上标注的 @MyTest4
注解信息。它借助 JUnit 的 @Test
注解来执行测试方法,验证注解的属性值是否能被正确获取。
代码功能解析
类中包含两个测试方法,分别用于解析类级别和方法级别的 @MyTest4
注解:
关键技术点
-
JUnit 的
@Test
注解:
标记这两个方法为测试方法,可通过 JUnit 测试框架直接运行(无需编写main
方法)。 -
反射机制:
Class c1 = Demo.class
:获取类的元数据对象(Class
实例)。isAnnotationPresent(MyTest4.class)
:判断目标(类 / 方法)是否标注了指定注解。getAnnotation(MyTest4.class)
:获取注解的实例,进而读取其属性值。
-
注解属性读取:
通过注解实例的 getter 方法(如myTest4.value()
、myTest4.aaa()
)获取注解中定义的属性值。
总结:
本文介绍了Java自定义注解@MyTest4的实现与应用。该注解可标记在类和方法上,包含三个属性:value(字符串)、aaa(带默认值的double类型)和bbb(字符串数组)。通过反射机制,程序能在运行时读取注解信息,如测试类AnnotationTest3所示,它通过反射获取Demo类及其方法上的注解属性值。这种机制常用于框架开发、测试工具等场景,为程序提供灵活的元数据支持。