空指针带来的日常不可避免的一些问题
1.写太多的if-else在程序提交给sona代码质量检测工具的时候,会遇到分析问题,提示方法的复杂度过高
for循环和if-else以及三目运算符都会增加方法的复杂度,复杂度越高,可读性越低
2.随着项目的迭代,项目的方法变得复杂不易读,过多的if-else嵌套非常影响编码格式带来的阅读问题,也会加大重构的难度
规避策略
1.前端传入后台参数时,利用@Valid或者@Validate做参数校验控制
在某些情况下,如果BeanValidator策略无法满足时,我们可以自定义校验策略,通过自定义编写注解校验类
/**
* @author liulei, [email protected]
* @version 1.0
*/
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = { PhoneNoValidator.class})
public @interface PhoneNo {
//默认错误消息
String message() default "电话号码错误";
//分组
Class<?>[] groups() default { };
//负载
Class<? extends Payload>[] payload() default { };
//指定多个时使用
@Target({ FIELD, METHOD, PARAMETER, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Documented
@interface List {
PhoneNo[] value();
}
}
/**
* @author liulei, [email protected]
* @version 1.0
*/
public class PhoneNoValidator implements ConstraintValidator<PhoneNo, String> {
@Override
public void initialize(PhoneNo constraintAnnotation) {
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (StringUtils.isEmpty(value)) {
return false;
}
if (value.matches(Constants.MOBILE_REGULAR) || value.matches(Constants.FIX_PHONE_REGULAR)) {
return true;
}
return false;
}
}
/**
* 客户联系方式
*/
@PhoneNo(message = "联系方式格式错误")
private String mobileNumber;
2.方法在使用到不应为null的参数时,先校验或者断言
// 1.利用assert
ssert param != null;
// 2.利用Objects的静态方法
Objects.nonNull(param, "xxx不能为空")
// 3.guava包的静态方法
Preconditions.checkNotNull等
3.提供公共的避免null取值的方法,最好是写在工具类中
适用于系统特定的一些为null的取值默认策略
4.使用lambda的Option静态方法来替代三目运算符
5.拆解方法体,分散在各个方法中,增强可读性,保留方法的主体处理流程即可
上层思想
1.设计之初,设置好每一个从数据库中的默认值,哪些是必须有的值,少用if-else来判断
2.不建议在实体类的get/set方法来处理null,会影响数据的初始状态,容易产生不可预知的问题