Java 自定义注解的实现与解析注解信息
文章目录
- 一.自定义注解的格式
- 二.自定义注解demo
- 三. 注解与类的关系
- 四. 解析注解的信息
- 4.1 解析注解在类的信息
- 4.2 解析注解在成员变量上的信息
- 4.3 解析注解在方法上的信息
一.自定义注解的格式
注解由于都是给其他的类中使用的, 所以一般都定义为public
注解属性支持的类型
- 所有的基本数据类型 8个
- String类型
- Class类型
- Enum 类型
- Annotation类型
- 以上所有类型的数据
注解是不能直接去继承其他的注解的.
二.自定义注解demo
自定义一个人的描述注解
// 该注解作用于成员变量上
@Target(ElementType.FIELD)
// 该注解的生命周期是运行时, 可以通过反射获取信息
@Retention(RetentionPolicy.RUNTIME)
public @interface PersonInfoAnnotation {
// 名字
public String name();
public int age() default 19;
public String gender() default "男";
// 开发语言
public String[] language();
}
自定义一个课程信息描述的注解
// 该注解作用于类和方法上
@Target({ ElementType.TYPE, ElementType.METHOD})
// 该注解的生命周期是运行时, 可以通过反射获取信息
@Retention(RetentionPolicy.RUNTIME)
public @interface CourseInfoAnnotation {
// 课程名称
public String courseName();
// 课程标签
public String courseTag();
// 课程简介
public String courseProfile();
// 课程序号
public int courseIndex() default 101;
}
定义一个课程的类MyCourse, 用注解来描述其相关信息
package demo.annotation;
/** * 类名称:MyCourse * * @author: https://javaweixin6.blog.csdn.net/ * 创建时间:2021/2/21 13:49 * Version 1.0 */
@CourseInfoAnnotation(courseName = "Java注解学习", courseTag = "注解", courseProfile = "零基础学习注解开发")
public class MyCourse {
@PersonInfoAnnotation(name = "周杰伦写代码", language = { "java", "javaScript"})
private String author;
@CourseInfoAnnotation(courseName = "java多线程学习", courseTag = "多线程", courseProfile = "从0开始学多线程", courseIndex = 666)
public void getCourseInfo(){
}
}
运行上面类中的getCourseInfo方法
public class AnnotationDemo {
public static void main(String[] args) {
MyCourse myCourse = new MyCourse();
myCourse.getCourseInfo();
System.out.println("执行完成");
}
}
执行结果如下, 可以看到注解没有影响其Java类的相关代码执行.
三. 注解与类的关系
下图可以看到Class 类实现了AnnotatedElement接口. AnnotatedElement接口是与注解相关的接口.
通过如下的类图可以看到AnnotatedElement是顶级接口, 与反射相关的Class , Field. Method , Constructor 其本质都实现了AnnotatedElement接口
此接口常用的方法有如下的三个.getAnnotation(Class<T> annotationClass)
获取某一个注解, 包含继承过来的注解Annotation[] getAnnotations();
获取所有的注解, 包含继承过来的default boolean isAnnotationPresent
用于判断是否包含指定的注解元素, 如果包含返回true, 如果不包含,返回false.
四. 解析注解的信息
4.1 解析注解在类的信息
创建一个AnnotationParser 类, 用于解析注解的信息.
如下的代码 . 解析了上面的步骤中MyCourse类的, 标注在其类上的CourseInfoAnnotation注解的信息.
public class AnnotationParser {
public static final String enterStr = "\n";
// 解析类上的注解信息
public static void parseTypeAnnotation() {
Class<MyCourse> clazz = MyCourse.class;
// 获取类上的注解信息
Annotation[] annotations = clazz.getAnnotations();
// 遍历上的所有的注解
for (Annotation annotation : annotations) {
// 注解进行强制类型转换
CourseInfoAnnotation courseInfoAnnotation = (CourseInfoAnnotation) annotation;
// 逐一获取注解的相关信息
System.out.println("课程名: " + courseInfoAnnotation.courseName() + enterStr +
"课程标签: " + courseInfoAnnotation.courseTag() + enterStr +
"课程简介: " + courseInfoAnnotation.courseProfile() + enterStr +
"课程序号: " + courseInfoAnnotation.courseIndex());
}
}
public static void main(String[] args) {
parseTypeAnnotation();
}
}
打印结果如下, 说明成功解析了在其类上的注解信息 .
4.2 解析注解在成员变量上的信息
public static final String enterStr = "\n";
// 解析成员变量上的注解信息
public static void parseFieldAnnotation() {
Class<MyCourse> clazz = MyCourse.class;
// 获取所有的成员变量
Field[] fields = clazz.getDeclaredFields();
// 遍历所有的成员变量
for (Field field : fields) {
// 判断成员变量中是否有指定类型的注解
boolean isAnnotationPresent = field.isAnnotationPresent(PersonInfoAnnotation.class);
if (isAnnotationPresent) {
PersonInfoAnnotation personInfoAnnotation = field.getAnnotation(PersonInfoAnnotation.class);
System.out.println("名字: " + personInfoAnnotation.name() + enterStr +
"年龄: " + personInfoAnnotation.age() + enterStr +
"性别: " + personInfoAnnotation.gender() + enterStr);
String[] languages = personInfoAnnotation.language();
for (String language : languages) {
System.out.println("课程名: " + language);
}
}
}
}
public static void main(String[] args) {
parseFieldAnnotation();
}
通过上面的图片可以看到成功解析了注解在成员变量上的信息. 其中年龄和性别取的默认值.
4.3 解析注解在方法上的信息
public static final String enterStr = "\n";
// 解析方法上的注解信息
public static void parseMethodAnnotation() {
Class<MyCourse> clazz = MyCourse.class;
// 获取所有的方法
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
boolean isAnnotationPresent = method.isAnnotationPresent(CourseInfoAnnotation.class);
// 判断是否有特定的注解
if (isAnnotationPresent) {
//强制转换为特定的注解
CourseInfoAnnotation courseInfoAnnotation = method.getAnnotation(CourseInfoAnnotation.class);
System.out.println("课程名: "+courseInfoAnnotation.courseName()+enterStr+
"课程标签: "+courseInfoAnnotation.courseTag()+enterStr+
"课程简介: "+courseInfoAnnotation.courseProfile()+enterStr+
"课程序号: "+courseInfoAnnotation.courseIndex()+enterStr);
}
}
}
public static void main(String[] args) {
parseMethodAnnotation();
}
结果打印如下
通过下图可以看到成功的获取了方法上的注解信息.
当把注解上的Retention从RUNTIME 改为CLASS或SOURCE 时 , 如下图所示
再次执行上面的获取注解信息的方法 , 结果如下图所示, 获取到的是空白的信息, 因此如果要获取注解中的信息, Retention要使用RUNTIME
还没有评论,来说两句吧...