代码优雅之道——Java如何判空

简介: 实际项目中我们会有很多地方需要判空校验,如果不做判空校验则可能产生NullPointerException异常。针对异常的处理我们在上一篇有提及:

1、前言
实际项目中我们会有很多地方需要判空校验,如果不做判空校验则可能产生NullPointerException异常。
针对异常的处理我们在上一篇有提及:
先来看一下实际项目中一些判空方式

通常我们判断一个对象是否为Null,可以使用java.util中的Objects.nonNull(obj)、hutool中的ObjectUtil或者直接 null != obj
2、List的判空
像List这种比较特殊的在项目中可能不仅仅是判断非空了。对于List来说不等于null和List.size()不等于0是两回事,公司也有实习生常常有把这两个混淆的情况,list不等于null说明已经初始化了,堆内存中有一块属于它的地盘,而size为0说明还没往里面放东西,举个例子说就是不等于null代表我现在有个瓶子,size大于0说明我向瓶子里装水了。
实际项目中也发现有直接用list.isEmpty()去判断的,来看一下源码:

相当于判断瓶子里有没有水(前提是瓶子已经存在,若瓶子不存在,则会抛出NullPointerException异常)。
所以通常情况下会连用list != null && list.size > 0 来判断,或者直接使用HuTool中CollUtil工具的isEmpty。诸如此类的还有Set、Map等
3、String的判空
这里还是用瓶子与水的概念,String为null时调用equals(String) 或 length() 等操作抛出 java.lang.NullPointerException。

针对字符串判空有以下几种方式:
1、大多数人使用的方法之一,直观,方便,但效率低下:
if(a == null || a.equals(""));
2、比较字符串长度,高效:
if(a == null || a.length() == 0);
3、Java SE 6.0 才刚刚开始提供,效率和方法二差不多:
if(a == null || a.isEmpty());
当然还可以使用org.apache.commons.lang.StringUtils工具。
StringUtils.isNotBlank(a);

  • StringUtils.isNotBlank(null) = false
  • StringUtils.isNotBlank("") = false
  • StringUtils.isNotBlank(" ") = false
  • StringUtils.isNotBlank("bob") = true
  • StringUtils.isNotBlank(" bob ") = true

该工具类中还有个isNotEmpty()方法,从注释可以很明显看出二者的差别
StringUtils.isNotEmpty(a);

  • StringUtils.isNotEmpty(null) = false
  • StringUtils.isNotEmpty("") = false
  • StringUtils.isNotEmpty(" ") = true
  • StringUtils.isNotEmpty("bob") = true
  • StringUtils.isNotEmpty(" bob ") = true

4、Optional
Optional的出现就是用来防止NullpointException的。常见的方法有:

.empty():创建一个空的Optional实例
.of(T t) : 创建一个Optional 实例,为null时报异常
.ofNullable(T t):若t 不为null,创建Optional 实例,否则创建空实例
isPresent() : 判断容器中是否有值
ifPresent(Consume lambda) :容器若不为空则执行括号中的Lambda表达式
orElse(T t) : 获取容器中的元素,若容器为空则返回括号中的默认值
orElseGet(Supplier s) :如果调用对象包含值,返回该值,否则返回s 获取的值
orElseThrow() :如果为空,就抛出定义的异常,如果不为空返回当前对象
map(Function f): 如果有值对其处理,并返回处理后的Optional,否则返回Optional.empty()
flatMap(Function mapper):与map 类似,要求返回值必须是Optional
T get() :获取容器中的元素,若容器为空则抛出NoSuchElement异常

先看个常见的示例:
baseInfo类中有布尔类型的属性,是空返回false,不为空取其值,需要四行。

当使用Optional时,一行搞定,非常的优雅。

4.1 Optional对象的创建
public final class Optional {

private static final Optional<?> EMPTY = new Optional<>();
private final T value;
//可以看到两个构造方格都是private 私有的
//说明 没办法在外面new出来Optional对象
private Optional() {
    this.value = null;
}
private Optional(T value) {
    this.value = Objects.requireNonNull(value);
}
//这个静态方法大致 是创建出一个包装值为空的一个对象因为没有任何参数赋值
public static<T> Optional<T> empty() {
    @SuppressWarnings("unchecked")
    Optional<T> t = (Optional<T>) EMPTY;
    return t;
}
//这个静态方法大致 是创建出一个包装值非空的一个对象 因为做了赋值
public static <T> Optional<T> of(T value) {
    return new Optional<>(value);
}
//这个静态方法大致是 如果参数value为空,则创建空对象,如果不为空,则创建有参对象
public static <T> Optional<T> ofNullable(T value) {
    return value == null ? empty() : of(value);
}

}
复制代码
4.2使用场景
场景1:在service层中 查询一个对象,返回之后判断是否为空并做处理

场景2:使用Optional 和函数式编程,一行搞定

5、总结
每种方法的存在必然有适用的场景,有些情况下这种链式编程,虽然代码优雅了。但是,逻辑性没那么明显,可读性有所降低,大家项目中看情况酌情使用。

相关文章
|
13天前
|
Java
在 Java 中捕获和处理自定义异常的代码示例
本文提供了一个 Java 代码示例,展示了如何捕获和处理自定义异常。通过创建自定义异常类并使用 try-catch 语句,可以更灵活地处理程序中的错误情况。
|
28天前
|
XML 安全 Java
Java反射机制:解锁代码的无限可能
Java 反射(Reflection)是Java 的特征之一,它允许程序在运行时动态地访问和操作类的信息,包括类的属性、方法和构造函数。 反射机制能够使程序具备更大的灵活性和扩展性
37 5
Java反射机制:解锁代码的无限可能
|
24天前
|
jenkins Java 测试技术
如何使用 Jenkins 自动发布 Java 代码,通过一个电商公司后端服务的实际案例详细说明
本文介绍了如何使用 Jenkins 自动发布 Java 代码,通过一个电商公司后端服务的实际案例,详细说明了从 Jenkins 安装配置到自动构建、测试和部署的全流程。文中还提供了一个 Jenkinsfile 示例,并分享了实践经验,强调了版本控制、自动化测试等关键点的重要性。
59 3
|
29天前
|
存储 安全 Java
系统安全架构的深度解析与实践:Java代码实现
【11月更文挑战第1天】系统安全架构是保护信息系统免受各种威胁和攻击的关键。作为系统架构师,设计一套完善的系统安全架构不仅需要对各种安全威胁有深入理解,还需要熟练掌握各种安全技术和工具。
83 10
|
25天前
|
分布式计算 Java MaxCompute
ODPS MR节点跑graph连通分量计算代码报错java heap space如何解决
任务启动命令:jar -resources odps-graph-connect-family-2.0-SNAPSHOT.jar -classpath ./odps-graph-connect-family-2.0-SNAPSHOT.jar ConnectFamily 若是设置参数该如何设置
|
23天前
|
Java
Java代码解释++i和i++的五个主要区别
本文介绍了前缀递增(++i)和后缀递增(i++)的区别。两者在独立语句中无差异,但在赋值表达式中,i++ 返回原值,++i 返回新值;在复杂表达式中计算顺序不同;在循环中虽结果相同但使用方式有别。最后通过 `Counter` 类模拟了两者的内部实现原理。
Java代码解释++i和i++的五个主要区别
|
2月前
|
搜索推荐 Java 数据库连接
Java|在 IDEA 里自动生成 MyBatis 模板代码
基于 MyBatis 开发的项目,新增数据库表以后,总是需要编写对应的 Entity、Mapper 和 Service 等等 Class 的代码,这些都是重复的工作,我们可以想一些办法来自动生成这些代码。
33 6
|
10天前
|
Java 开发者
Java多线程编程中的常见误区与最佳实践####
本文深入剖析了Java多线程编程中开发者常遇到的几个典型误区,如对`start()`与`run()`方法的混淆使用、忽视线程安全问题、错误处理未同步的共享变量等,并针对这些问题提出了具体的解决方案和最佳实践。通过实例代码对比,直观展示了正确与错误的实现方式,旨在帮助读者构建更加健壮、高效的多线程应用程序。 ####
|
1天前
|
缓存 Java 开发者
Java多线程编程的陷阱与最佳实践####
本文深入探讨了Java多线程编程中常见的陷阱,如竞态条件、死锁和内存一致性错误,并提供了实用的避免策略。通过分析典型错误案例,本文旨在帮助开发者更好地理解和掌握多线程环境下的编程技巧,从而提升并发程序的稳定性和性能。 ####
|
1天前
|
安全 Java 开发者
Java中的多线程编程:从基础到实践
本文深入探讨了Java多线程编程的核心概念和实践技巧,旨在帮助读者理解多线程的工作原理,掌握线程的创建、管理和同步机制。通过具体示例和最佳实践,本文展示了如何在Java应用中有效地利用多线程技术,提高程序性能和响应速度。
16 1
下一篇
无影云桌面