前言
关于参数校验,一直是个困扰人的事。这次使用注解+反射,实现自己的非空校验。
1 自定义注解 NotNull
package com.example;
import java.lang.annotation.*;
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface NotNull {
String errorMsg();
}
2 使用接口实现 NotNull注解的功能
package com.example;
import java.lang.reflect.Field;
public interface Check {
default void doCheck() {
final Field[] declaredFields = this.getClass().getDeclaredFields();
for (Field declaredField : declaredFields) {
if (Check.class.isAssignableFrom(declaredField.getType()) || declaredField.isAnnotationPresent(NotNull.class)) {
declaredField.setAccessible(true);
deepCheck(declaredField);
}
}
}
private void deepCheck(Field declaredField) {
try {
final Object declaredFieldValue = declaredField.get(this);
if (declaredFieldValue instanceof Check) {
((Check) declaredFieldValue).doCheck();
return;
}
if (declaredFieldValue == null && declaredField.isAnnotationPresent(NotNull.class)) {
final NotNull notNull = declaredField.getAnnotation(NotNull.class);
final String errorMsg = notNull.errorMsg();
throw new IllegalArgumentException(errorMsg);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
3 测试效果
package com.example;
public class MainClient implements Check {
@NotNull(errorMsg = "check2不能为空")
private Check2 check2;
@NotNull(errorMsg = "aaa")
private String aaa;
public static void main(String[] args) {
MainClient client = new MainClient();
client.check2 = new Check2();
client.doCheck();
}
}
class Check2 implements Check {
@NotNull(errorMsg = "aaa不能为空")
private String aaa="";
}
4 控制台的异常栈信息
Exception in thread "main" java.lang.IllegalArgumentException: aaa
at com.example.Check.deepCheck(Check.java:31)
at com.example.Check.doCheck(Check.java:16)
at com.example.MainClient.main(MainClient.java:14)
|