Java笔记 ·

函数出错返回的数据类型

函数出错返回的数据类型有4中情况:错误码NULL值空对象异常对象

1. 错误码

  • C语言中没有异常这样的语法机制,返回错误码便是最常用的的出错处理方式。
  • Java、Python等比较新的编程语言中,大部分情况下,我们都用异常来处理函数出错的情况,极少会用到错误码。

2. 返回NULL值

  • 多数编程语言中,NULL用来表示“不存在”的语义。
  • 对于查找函数(get、find、select、search、query 等单词开头的函数),数据不存在是一种正常行为,并非是一种异常情况,所以返回表示不存在语义的NULL值比返回异常更合理。

2.1 弊端

很多人认为返回NULL值是一种不好的设计思路的两个主要理由:

  • 若函数可能返回NULL值,当使用时忘记做NULL值判断,可能会抛出空指针异常(Null Pointer Exception,NPE)。
  • 若定义了很多返回值可能为NULL值的函数,代码中会充斥大量的NULL值判断逻辑,写起来比较繁琐,同时和正常业务逻辑耦合在一起,影响代码可读性。

3. 返回空对象

返回NULL值有各种弊端,对此有一个比较经典的应对策略,就是应用空对象设计模式(Null Object Design Pattern)。

当函数返回的数据是字符串类型或者集合类型的时候,我们可以用空字符串或空集合替代 NULL 值,来表示不存在的情况。这样,我们在使用函数的时候,就可以不用做 NULL 值判断。

public List<User> getUsers(String phonePrefix) {
    // 未找到数据
    return Collections.emptyList();
}

public String getUserName(Long id) {
    // 未找到数据
    return "";
}

4. 抛出异常对象

最常用的函数出错处理方式是抛出异常。异常有两种类型:受检异常和非受检异常。

至于孰好孰坏,只需要根据团队的开发习惯,在同一个项目中,制定统一的异常处理规范即可。

对于函数抛出的异常,我们有三种处理方法:直接吞掉、直接往上抛出、包裹成新的异常抛出。

返回 NULL 值还是异常对象,要看获取不到数据是正常行为,还是异常行为。获取信息失败会影响后续逻辑的处理,并不是我们期望的,此时便是一种异常行为,最好抛出异常。

我们需要明确地告知调用者的异常时不可直接吞掉。

4.1 是否要在函数中做 NULL 值或空字符串的判断

  • 如果函数是 private 类私有的,只在类内部被调用,完全在你自己的掌控之下,自己保证在调用这个 private 函数的时候,不要传递 NULL 值或空字符串就可以了。所以,我们可以不在 private 函数中做 NULL 值或空字符串的判断。
  • 如果函数是 public 的,你无法掌控会被谁调用以及如何调用(有可能某个同事一时疏忽,传递进了 NULL 值,这种情况也是存在的),为了尽可能提高代码的健壮性,我们最好是在 public 函数中做 NULL 值或空字符串的判断。

4.2 需要包裹成新异常抛出的条件

  • 当依赖抽象而非实现编程,即调用者调用函数时只知道功能不需要知道底层实现时,直接抛出底层异常实际上暴露了实现细节。
  • 从代码封装的角度,并不希望将比较底层的异常暴露给更上层的代码,而且调用者拿到该异常时并不能理解这个异常到底代表了什么,也不知道该如何处理。
  • 异常跟调用者调用的函数,在业务概念上没有相关性。

参考资料

设计模式之美

参与评论