📢📢📢 最近我们团队在翻译《Effective Kotlin: Best practices》,关注我们,我们会定时更新,欢迎指正,欢迎收藏 😁
条目 6:优先考虑使用标准库中的异常类型而不是自定义异常类型
翻译: zhiyueli
校对: levin
TL; DR:
任何时候都应该尽可能使用标准库中已有的异常类型,而不是自定义异常类型,因为标准库异常类型更被开发者熟知和理解。
有时候我们需要在代码中主动抛出异常以表明这里有可能出现的错误,比如,当我们实现一个解析 JSON
的方法,我们需要在 JSON
格式不合法的时候抛出一个 JsonParsingException
异常:
inline fun <reified T> String.readObject(): T {
//...
if (incorrectSign) {
throw JsonParsingException()
}
//...
return result
}
在这里我们使用了一个自定义的异常类型,因为标准库中没有特别适合表述 JSON
格式不合法导致解析失败的异常类型。任何时候,我们都应该尽可能优先使用标准库中已有的异常类型而不是自定义异常类型,因为标准库中的异常类型都是开发者所熟知且应该被复用的一些类型,复用大家更为熟悉的异常类型意味着我们写出来的代码更容易被理解和使用。这里列举一些常用的标准库中的异常类型:
-
IllegalArgumentException
和IllegalStateException
:这两个异常已经在 条目 5: 明确对参数和状态的预期条件 中介绍过了,我们会通过require
和check
抛出这两个异常。 -
IndexOutOfBoundsException
:表示 index 超出合法范围的异常。特别是在集合和数组中,比如ArrayList.get(Int)
中就用到了这个异常类型 -
ConcurrentModificationException
:表示禁止并发修改的异常 -
UnsupportedOperationException
:表示所定义的方法不允许被当前类使用。应该避免这种情况的发生,如果一个方法不允许被使用的话,那就不应该定义在这个类里面。在 ISP (接口隔离原则) 中也说道:不应强迫任何类依赖它不使用的方法。译者注:Java 源码中使用到这个异常的其中一个场景就是在
EmptyList
的中:EmptyList
并没有重写add
方法,而其父类AbstractList
的add
实现就是直接抛出一个UnsupportedOperationException
。空列表不允许被添加任何元素进来,这看起来挺合理的,但是根据 ISP 原则,一个类不应该依赖他不需要的方法,我们应该尽量避免有这种场景发生。 -
NoSuchElementException
:表示一个正在被访问的元素不存在的异常。比如我们在使用Iterable
去遍历元素的时候,当我们尝试访问next
但是集合中并没有更多元素时就会抛出这个异常。