再见 NullPointerException,一个工具类消灭所有空异常!
共 3090字,需浏览 7分钟
· 2023-09-18
你知道的越多,不知道的就越多,业余的像一棵小草!
你来,我们一起精进!你不来,我和你的竞争对手一起精进!
编辑:业余草
推荐:https://t.zsxq.com/12FEd8lJL
自律才能自由
不知道从什么时间开始,Java 程序员和空异常 NullPointerException 干上了,百度出来的文章超过 3000 多万,而且流量还很大。
最近,针对 NullPointerException 问题,我借鉴了一些函数式编程,封装了一个工具类。今天把核心代码分享给大家。
// 正常业务逻辑
if( context != null && context.getType() != null){
//执行某些逻辑。
}
以上我们系统中常见的代码,做了两次非空判断,稍不留神,忘了判断context为空,就会出现空指针异常 NullPointerException。空指针的发生是大多因为开发者忘记进行判空,那如何有效避免空指针呢?
拿我们的系统来举例,项目主流程中新增了一个 context 对象,这个对象某些场景可能为 Null,并且 Context 中的属性也可能为 Null。
为避免潜在的空指针异常,我打算封装工具方法供开发者使用,无需开发者主动判空,只要使用这个工具方法,就可以安全的访问 Context。
Optional 和 Lamada 判空
我这里写了一个通用方法,用过后真香,大家细品。
@Nullable
public static <T, R> R getValue(T r, Function<? super T, ? extends R> function) {
//如果 r = null, 调用map时 会自动返回Null,不会出现空指针
return Optional.ofNullable(r).map(function).orElse(null);
}
public static <T, R> R valueNotNull(T r, Function<? super T, ? extends R> function) {
//如果 r = null, 调用map时 会自动返回Null,不会出现空指针
return Optional.ofNullable(r).map(function).orElse(null) != null;
}
刚才context.getType()
判空的代码,使用valueNotNull
工具类重写一下。
if(valueNotNull(context, Context::getType)){
//执行某些逻辑。
}
valueNotNull(Optional.ofNullable(r).map(function).orElse(null)
做了两个事情。
-
如果 context 为空,那么跳过 Map 直接返回 Null -
如果 Context 不为空,那么如果执行 lamada 表达式(Context::getType),如果不存在则为Null,并再次判空。
这样通过工具方法,我们就不会再出现漏写判空语句导致的空指针异常,形成代码 CodeReview 规范。
三层非空判断
如果有三层非空判断,则再增加一个 lamada 表达式、增加一次 map() 即可。
@Nullable
public static <T, R, E> E valueNotNull(T r, Function<? super T, ? extends R> function,
Function<? super R, ? extends E> function2) {
//如果 r = null, 调用map时 会自动返回Null,不会出现空指针
return Optional.ofNullable(r).map(function).map(function2).orElse(null)!=null;
}
//使用Java8 lamada表达式
if(valueNotNull(context, Context::getParam, Param::getType())){
//执行业务逻辑
}
//原始的方式
if(context!=null && context.getParam()!=null && context.getParam().getType()!=null){
// 执行业务逻辑
}
以上的代码和具体的类无关,如果你的代码中通过多级调用,且每一级都可能为空,可以考虑这个工具类,简化代码设计。
空指针是代码中常出现的异常,有效避免空指针之一就是,基于Lamada表达式,为提供可能为空值字段提供特殊的访问方法。
完整代码参见https://t.zsxq.com/12toYSneX
。