因业务需求,要给为null的属性一个默认值,用java代码判断非常繁琐,所以我尝试使用自定义注解来对对象中的属性判断值并给默认值。
首先创建一个自定义注解:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @description: 自定义注解->用来校验参数是否为null,如果为null,则根据数据类型不同给不同的默认值
* @author: Mr.Wang
* @create: 2019-05-17 14:00
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ParamsCheck {
boolean require() default true;
}
而后创建一个相关业务实体类的父类,然后将需要用到上面注解的实体继承该父类
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* @description: 实体父类 用于实现自定义注解
* @author: Mr.Wang
* @create: 2019-05-17 14:00
**/
@Slf4j
public class BaseEntity {
/**
* 判断是否标记ParamsRequired 注解,如果标记,则做判空处理并给出默认值
*/
public void validate() {
Field[] fields = this.getClass().getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(ParamsCheck.class)) {
ParamsCheck paramsCheck = field.getAnnotation(ParamsCheck.class);
if (paramsCheck.require()) {
// 判断数据类型为String integer date
if (field.getGenericType().toString().equals("class java.lang.String") ||
field.getGenericType().toString().equals("class java.lang.Integer")) {
try {
// 得到当前属性的get方法
Method getter = this.getClass().getMethod("get" + getMethodName(field.getName()));
// 调用get方法获得属性值
String value = (String) getter.invoke(this);
// 判断属性值是否为null
if (null == value) {
log.info("param {} is null , Please check.", field.getName());
if (field.getGenericType().toString().equals("class java.lang.String")) {
Method setString = this.getClass().getMethod("set" + getMethodName(field.getName()), String.class);
// set一个空串
setString.invoke(this, "");
} else if (field.getGenericType().toString().equals("class java.lang.Integer")) {
Method setInteger = this.getClass().getMethod("set" + getMethodName(field.getName()), Integer.class);
// set 0
setInteger.invoke(this, 1);
}
}
} catch (Exception e) {
log.info("An exception has occurred with the current custom annotation for ParamsCheck!!!", e);
}
}
}
}
}
}
/**
* 为了组成get方法(高效)
*
* @param fieldName 当前字段名
* @return 将当前字段名的首字母大写后返回
*/
private String getMethodName(String fieldName) throws Exception {
byte[] items = fieldName.getBytes();
items[0] = (byte) ((char) items[0] - 'a' + 'A');
return new String(items);
}
}
使用时要在继承该父类的实体属性上加上该注解:
@ParamsCheck
private String carLoginTimeStr;
然后在需要做属性判空的程序入口下调用validate()方法即可:
Student student = new Student();
student.validate();
思考:其实最开始设计此处的时候我想要AOP的方式来做,但是因为业务的关系,当前属性并不是在所有的时候都需要进行判断。所以在父类方法中加入了validate方法而不是用切面的形式来做。感兴趣的同学可以尝试使用AOP的方式实现以上功能,这样对于技术的理解也更加深刻。