MST

星途 面试题库

面试题:Java中自定义注解如何实现参数校验

在Java开发中,假设你需要自定义一个注解用于对方法参数进行非空校验,描述实现此功能的步骤,包括定义注解、编写注解处理器等。
43.0万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试
  1. 定义注解

    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.PARAMETER)
    public @interface NotNull {
        String message() default "参数不能为空";
    }
    
    • 使用@Retention(RetentionPolicy.RUNTIME)指定注解在运行时可用。
    • @Target(ElementType.PARAMETER)表明该注解用于方法参数。
    • 定义了一个message属性,用于在参数为空时提供提示信息。
  2. 编写注解处理器

    import java.lang.reflect.Method;
    import java.util.ArrayList;
    import java.util.List;
    
    public class NotNullProcessor {
        public static void validate(Object target, Method method, Object[] args) throws IllegalArgumentException {
            Annotation[][] parameterAnnotations = method.getParameterAnnotations();
            for (int i = 0; i < parameterAnnotations.length; i++) {
                for (Annotation annotation : parameterAnnotations[i]) {
                    if (annotation instanceof NotNull) {
                        if (args[i] == null) {
                            String message = ((NotNull) annotation).message();
                            throw new IllegalArgumentException(message);
                        }
                    }
                }
            }
        }
    }
    
    • 该处理器通过反射获取方法的参数注解。
    • 遍历参数注解,如果发现NotNull注解,检查对应参数是否为空,为空则抛出IllegalArgumentException异常,并附带注解中定义的错误信息。
  3. 使用示例

    public class ExampleService {
        public void doSomething(@NotNull String param) {
            System.out.println("参数: " + param);
        }
    }
    
    • ExampleService类的doSomething方法中使用@NotNull注解对param参数进行非空校验。
    • 调用方法时可以通过反射结合注解处理器进行校验:
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    public class Main {
        public static void main(String[] args) {
            ExampleService service = new ExampleService();
            try {
                Method method = ExampleService.class.getMethod("doSomething", String.class);
                NotNullProcessor.validate(service, method, new Object[]{null});
                method.invoke(service, "测试值");
            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | IllegalArgumentException e) {
                e.printStackTrace();
            }
        }
    }
    
    • main方法中,先通过反射获取方法,调用NotNullProcessor.validate方法进行参数校验,然后再调用实际方法。如果参数为空,会抛出异常。