改变习惯性 !=null 的判断,只需一秒!

科技   2024-12-20 11:24   陕西  
今天我们来聊聊一个程序员心头的“老大难”问题——空指针异常
你知道的,空指针异常(NullPointerException,简称NPE)在开发中是最常见的 bug 之一,它几乎伴随着每一个 Java 程序员的成长。
大家肯定都有过因为 != null 判断过多,导致代码变得冗长、难以阅读的经历。那么,如何优雅地处理这些空指针问题呢?今天我就和大家分享一下,我是如何一秒钟改变我的习惯,从而让代码变得更加简洁易懂的。

空指针异常的普遍性与问题

空指针异常,顾名思义,就是访问了一个 null 对象时引发的错误。在 Java 中,遇到 null 值时,程序员往往都会通过类似 if (obj != null) 来避免这种情况。这种方法在短期内确实有效,但长期来看,频繁使用 != null 判断,代码就会变得异常冗长,逻辑层次也不够清晰。别说是维护这个代码了,光是阅读,可能就要比读《红楼梦》还要辛苦。
我们不妨想象一下,如果你在写一段代码时,必须在每个 null 可能出现的地方都加上判断,那得加多少行 if 语句呀?🤦‍♂️ 最终,你会发现你的代码看起来像极了“嵌套大餐”,各类条件判断交织在一起,想理解其中的逻辑,简直像做了一个贼复杂的“解谜游戏”。

优化空指针判断的思路

那么,问题来了,怎样才能把这些零散的 null 判断优化掉呢?答案就是:工具类。通过使用一些工具类,我们可以把空指针判断的逻辑集中化,代码更加简洁,维护性更强,最重要的是,大家都能看懂!
我给大家提供一个简单的思路,分三步走:
  1. 分析数据类型:首先,你得搞清楚你判断的对象到底是什么类型,比如是 StringObjectList 还是 Map
  2. 选择合适的工具类:根据数据类型选择合适的工具类进行判断。不要自己去重复造轮子,很多常见的判断逻辑工具类已经帮我们处理好了。
  3. 使用工具类的方法:拿来主义!直接用工具类的方法代替自己手动写的 != null 判断。

常见数据类型的工具类判断

1. String 类型

对于 String 类型,直接判断它是否为空或者为 null,我们可以使用 Apache Commons Lang 提供的 StringUtils.isEmpty() 方法。这是一个非常常用的工具,判断一个字符串是否为空或为 null,简直就是秒杀传统的 if (str != null && !str.isEmpty())
示例代码:
String str = "";
StringUtils.isEmpty(str);  // 返回 true,因为 str 为空字符串
相比于手动的 if 判断,使用 StringUtils.isEmpty() 看起来要简洁、直观得多。👌

2. Object 类型

接下来是 Object 类型。对于一般对象的空值判断,Apache Commons Lang 也提供了 ObjectUtils.isEmpty() 方法。它可以判断对象是否为 null,所以我们再也不需要每次都写 if (obj != null) 了。
示例代码:
Object obj = null;
ObjectUtils.isEmpty(obj);  // 返回 true,因为 obj 为 null

3. Map 类型

对于 Map 类型的判断,ObjectUtils.isEmpty() 依然能派上用场。它不仅能判断 Map 是否为空,还能判断 Map 是否为 null。简直一举两得。
示例代码:
Map<String, Object> map = Collections.emptyMap();
ObjectUtils.isEmpty(map);  // 返回 true,因为 map 是空的

4. List 类型

我们再来看看 List 类型。ObjectUtils.isEmpty() 同样适用于 List。但这里需要注意的是,如果你要判断 List 中的元素是否为 null,这还得另做文章。我们后面会详细探讨。
示例代码:
List<Integer> list = Collections.emptyList();
ObjectUtils.isEmpty(list);  // 返回 true,因为 list 是空的

5. Array 类型

对于数组类型,ObjectUtils.isEmpty() 也能帮忙。它会判断数组是否为空,或者是否为 null
示例代码:
Object[] objArr = null;
ObjectUtils.isEmpty(objArr);  // 返回 true,因为 objArr 为 null

ObjectUtils.isEmpty() 方法的源码解析

下面,我们来看看 ObjectUtils.isEmpty() 方法是如何实现的。它通过 instanceof 判断不同的数据类型,然后调用相应的方法来进行空值判断。你可以看到它的简洁和高效。
源码简析:
public static boolean isEmpty(@Nullable Object obj) {
    if (obj == nullreturn true;
    if (obj instanceof Optional) return !((Optional) obj).isPresent();
    if (obj instanceof CharSequence) return ((CharSequence) obj).length() == 0;
    if (obj.getClass().isArray()) return Array.getLength(obj) == 0;
    if (obj instanceof Collection) return ((Collection) obj).isEmpty();
    if (obj instanceof Map) return ((Map) obj).isEmpty();
    return false;
}
通过这个方法,我们能够覆盖常见的数据类型,包括 OptionalCharSequenceArrayCollectionMap,省去了我们一个个手动写判断的麻烦。

存在的不足与改进

尽管 ObjectUtils.isEmpty() 功能强大,但它也有一个小小的不足。它并没有处理集合或数组中元素是否为 null 的判断。假设你有一个 ListArray,其中有一些元素为 null,如果你只是使用 ObjectUtils.isEmpty() 判断它们是否为空,它只能告诉你集合本身是否为空,而无法告诉你其中的元素是否为 null
针对这个问题,我们可以做进一步的改进:
Arrays.stream(list.toArray()).allMatch(ObjectUtils::isEmpty);
这样,你就可以遍历集合中的每个元素,判断它们是否为空了。

集合判断的其他工具类

除了 ObjectUtils.isEmpty(),我们还可以使用 CollectionUtils.isEmpty() 来判断 MapCollection(如 List)是否为空或为 nullCollectionUtils.isEmpty() 在判断时会考虑集合本身是否为空,并且它能够同时处理 null 和空集合。
示例代码:
CollectionUtils.isEmpty(map);  // 返回 true,如果 map 为 null 或空
CollectionUtils.isEmpty(list); // 返回 true,如果 list 为 null 或空

总结

好了,今天的内容我们总结一下:
  1. 分析数据类型:判断空值时,首先要考虑数据类型,比如是 StringList 还是 Map
  2. 选择合适的工具类:根据数据类型,选择合适的工具类来简化判断。比如 StringUtils.isEmpty()ObjectUtils.isEmpty()CollectionUtils.isEmpty()
  3. 使用工具类:使用这些工具类来减少冗余的 != null 判断,让代码更简洁、可读、易维护。
通过这些工具类的帮助,我们可以轻松避免无谓的空指针判断,使得代码看起来更简洁,逻辑更清晰,完全不再需要一堆 if (obj != null)。快试试吧,改掉这些“糟糕的习惯”,让你的代码更优雅!
对编程、职场感兴趣的同学,可以链接我,微信:coder301 拉你进入“程序员交流群”。
🔥东哥私藏精品 热门推荐🔥

东哥作为一名超级老码农,整理了全网最全《Java高级架构师资料合集》

资料包含了《IDEA视频教程》《最全Java面试题库》、最全项目实战源码及视频》及《毕业设计系统源码》总量高达 650GB 。全部免费领取!全面满足各个阶段程序员的学习需求。

Java面试那些事儿
回复 java ,领取Java面试题。分享AI编程,Java教程,Java面试辅导,Java编程视频,Java下载,Java技术栈,AI工具,Java开源项目,Java简历模板,Java招聘,Java实战,Java面试经验,IDEA教程。
 最新文章