⾃定义注解实现字段有条件的判空标签: java ⾃定义注解 判空
背景
⾃定义注解实现字段有条件的判空,例如Student有三个字段name、age、x;name、age不能为空,x只有当age=18时不能为空(可能例⼦不是很符合实际场景,只为实现说明)
代码实现
1、新建⾃动以注解类
基本元注解含义请⾃⾏学习@Target、@Retention、@Documented、@Inherited。本例@ConditionalNotEmpty注解有三个参数message、conditionFiledName、contionString,含义分别为错误提⽰信息、判断依据的字段名称、判断条件(如本例中如果age=18,则x不能为空)。可以⾃⾏设置参数默认值,如果参数没有默认值则在使⽤注解时必须要明确传递参数值什么是项目
package com.atguigu.springcloud.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ConditionalNotEmpty {
//错误提⽰信息
String message();
//判断依据的字段名称
String conditionFiledName() default "";
//判断条件,如本例中 18
String contionString() default "";
}
2、新建Student类
建议使⽤lombok注解减少代码量,可以看到注解的参数message必须赋值,否则会报错,conditionFiledName、contionString在⾃定义注解中已经执⾏默认值为"",所有不明确赋值也不会报错。在x字段使⽤注解的含义为如果age=18则x不能为空
import lombok.Data;
@Data
public class Student {
@ConditionalNotEmpty(message = "name不能为空")
private String name;
@ConditionalNotEmpty(message = "age不能为空")
private String age;
@ConditionalNotEmpty(message = "x不能为空",conditionFiledName = "age",contionString = "18") private String x;
public Student(String name, String age, String x) {
this.name = name;
this.age = age;
this.x = x;
}
@Override
瓦林卡public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age='" + age + '\'' +
", x='" + x + '\'' +
'}';
}
}
3、新建ConditionalNotEmptyExplain类
利⽤反射解析注解,详细注释如下代码。实际开发中可以直接调⽤也可以使⽤AOP去判空
import s.lang3.StringUtils;
import flect.Field;
public class ConditionalNotEmptyExplain {
public static <T> void validate(T t) throws IllegalAccessException, NoSuchFieldException {
// 获取当前对象所有字段信息
Field[] declaredFields = t.getClass().getDeclaredFields();
for (Field field : declaredFields) {
// 判断字段是否被注解 ConditionalNotEmpty 解释
if (field.isAnnotationPrent(ConditionalNotEmpty.class)) {
// 功能是启⽤或禁⽤安全检查,设置为true
field.tAccessible(true);
// (t)获取当前字段值,如果有值则判断下个字段
if ((t) != null) {
continue;
}
// (t)获取当前字段值,如果为空则继续判断是否需要条件判断奥利奥慕斯
ConditionalNotEmpty annotation = Annotation(ConditionalNotEmpty.class);
// 获取message参数值
String message = ssage();
// 获取conditionFiledName参数值
String conditionFiledName = ditionFiledName();
入团申请书格式模板// 获取contionString参数值
String contionString = ionString();
// 如果conditionFiledName和contionString不为空,则直接打印出message
if (StringUtils.isNotEmpty(conditionFiledName) && StringUtils.isNotEmpty(contionString)) {
// 根据依赖字段conditionFiledName(⽐如本例字段age),反射得到这个依赖字段的信息
Field conditionFiled = t.getClass().getDeclaredField(conditionFiledName);
conditionFiled.tAccessible(true);
// 获取当前依赖字段值(⽐如本例字段age)
Object conditionFiledValue = (t);
// 进⾏判断如果当前依赖字段值等于注解参数contionString值则满⾜条件(本例当前字段age值10等于注解参数contionString10,则打印) if (conditionFiledValue != null && contionString.equals(conditionFiledValue)) {
if ((t) == null) {
虫草鸽子汤
System.out.println("当"+Name()+"为"+conditionFiledValue+"时"+message);
continue;
}
}
}el {
// 如果conditionFiledName和contionString为空,则直接打印出message
System.out.println(message);
}
}
洞顶乌龙茶}
}
}
4、测试结果
// 1、当name、age、x都为空时
public class TestMain {
public static void main(String[] args) throws IllegalAccessException, NoSuchFieldException { Student student = new Student(null,null,null);
ConditionalNotEmptyExplain.validate(student);
}
}
控制台打印结果:
厉害我的国name不能为空
age不能为空
// 2、当age、x为空时
public class TestMain {
public static void main(String[] args) throws IllegalAccessException, NoSuchFieldException { Student student = new Student("zhangsan",null,null);
ConditionalNotEmptyExplain.validate(student);
}
}
控制台打印结果:
age不能为空
// 3、当age=18、x为空时
public class TestMain {
女孩儿英文名public static void main(String[] args) throws IllegalAccessException, NoSuchFieldException { Student student = new Student("zhangsan","18",null);
ConditionalNotEmptyExplain.validate(student);
}
}
控制台打印结果:
当age为18时x不能为空
// 4、当age=19、x为空时
public class TestMain {
public static void main(String[] args) throws IllegalAccessException, NoSuchFieldException { Student student = new Student("zhangsan","18",null);
ConditionalNotEmptyExplain.validate(student);
}
}
控制台打印结果:
没有打印结果