MST

星途 面试题库

面试题:Java中如何自定义一个注解并实现简单的解析器

请阐述自定义Java注解的步骤,包括元注解的使用。并编写一个简单的自定义注解,同时实现一个解析器,该解析器能在运行时获取使用了该注解的类、方法等元素,并打印相关信息。
17.7万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试
  1. 自定义Java注解步骤
    • 定义注解:使用 @interface 关键字定义注解。例如:
    public @interface MyAnnotation {
    }
    
    • 使用元注解
      • @Retention:用于指定注解的保留策略,有 RetentionPolicy.SOURCE(仅在源码中保留,编译时丢弃)、RetentionPolicy.CLASS(编译时保留在class文件中,但运行时JVM不会读取)、RetentionPolicy.RUNTIME(运行时JVM会读取,可以通过反射获取)。一般如果要在运行时获取注解,使用 RetentionPolicy.RUNTIME。例如:
      import java.lang.annotation.Retention;
      import java.lang.annotation.RetentionPolicy;
      
      @Retention(RetentionPolicy.RUNTIME)
      public @interface MyAnnotation {
      }
      
      • @Target:用于指定注解可以应用的目标元素类型,如 ElementType.TYPE(类、接口、枚举等类型)、ElementType.METHOD(方法)、ElementType.FIELD(字段)等。例如:
      import java.lang.annotation.ElementType;
      import java.lang.annotation.Retention;
      import java.lang.annotation.RetentionPolicy;
      import java.lang.annotation.Target;
      
      @Retention(RetentionPolicy.RUNTIME)
      @Target({ElementType.TYPE, ElementType.METHOD})
      public @interface MyAnnotation {
      }
      
  2. 编写简单自定义注解
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.TYPE, ElementType.METHOD})
    public @interface MyAnnotation {
        String value() default "";
    }
    
  3. 实现解析器
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    public class AnnotationParser {
        public static void parse(Object obj) {
            Class<?> clazz = obj.getClass();
            // 检查类上的注解
            if (clazz.isAnnotationPresent(MyAnnotation.class)) {
                MyAnnotation annotation = clazz.getAnnotation(MyAnnotation.class);
                System.out.println("类 " + clazz.getName() + " 上的注解值: " + annotation.value());
            }
            // 检查方法上的注解
            Method[] methods = clazz.getDeclaredMethods();
            for (Method method : methods) {
                if (method.isAnnotationPresent(MyAnnotation.class)) {
                    MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
                    System.out.println("方法 " + method.getName() + " 上的注解值: " + annotation.value());
                }
            }
            // 检查字段上的注解(如果注解支持字段,这里未在示例注解中设置对字段支持,仅为演示完整获取流程)
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                if (field.isAnnotationPresent(MyAnnotation.class)) {
                    MyAnnotation annotation = field.getAnnotation(MyAnnotation.class);
                    System.out.println("字段 " + field.getName() + " 上的注解值: " + annotation.value());
                }
            }
        }
    }
    
  4. 使用示例
    @MyAnnotation("类注解示例")
    public class MyClass {
        @MyAnnotation("方法注解示例")
        public void myMethod() {
        }
    }
    
    在测试类中调用解析器:
    public class Main {
        public static void main(String[] args) {
            MyClass myClass = new MyClass();
            AnnotationParser.parse(myClass);
        }
    }
    

上述代码首先定义了一个自定义注解 MyAnnotation,并使用 @Retention@Target 元注解设置其保留策略为运行时且可应用于类和方法。然后实现了一个解析器 AnnotationParser 来获取并打印使用了该注解的类和方法的相关信息。最后给出了使用示例及测试代码。