关于Kotlin抛弃可检测的异常处理,你怎么看?

可检测的异常英文翻译为Checked Exception,以下简称为CE。CE是一个备受争议的话题,有人主张CE是一个不可或缺的特性,也有人认为CE带来了一些问题,是一个冗余特性。这其中的支持者和反对者中都不乏软件行业的大佬。今天,我们借助这篇文章一起来讨论一下CE存在的必要性。

什么是CE

部分同学可能还不知道CE到底是什么。因此,在开始命题之前,有必要给大家解释一下CE的概念。

CE其实你每天都在用,只是你不知道它的存在而已。看一个例子你就明白了:

1
public void readString() throws IOException, FileNotFoundException {}

在这个函数声明的最后面,我们指定了函数可能抛出的异常,在使用的时候我们就可以针对具体的异常使用try {} catch() {}进行处理了。

由于我们在方法声明中指定了可能抛出的异常,因此方法具体可能抛出的异常是已知的,这就称之为可检测的异常(CE)。由于CE的声明来自编译阶段,因此IDE可能帮助你智能判断强制你针对某些异常进行处理,并给出友好提示。

这是一个很好的特性,不是吗?

想象一下,如果有一天,我们不能在函数上指定可抛出的异常了,会怎样?我们无法确定函数可能抛出的异常,并且可能会因为没有正确处理某个异常而导致程序奔溃。

可是,就是有人认为CE多此一举,并且Kotlin语言就是其中的支持者。为什么会有人坚定地认为CE多此一举呢?这是下一个我们要讨论的话题。

关于CE的争论

Java语言的CE设计借鉴了C++,而在受到Java影响的那些语言中,例如C#、Ruby等都去掉了CE的设计,这从实践的角度证明CE的存在确实意义不大。

在这个问题中,C#的主导工程师Anders Hejlsberg最有发言权。老实说,笔者并没有用过C#。可是,如果你搜索一下网络上关于C#和Java对比的文章你就会发现:C#被认为是一门比Java更优秀的编程语言,它始终在新增一些现代语言的特性,使你毫不费力地使用它。而Java作为一门古老的语言,受限于一些原始设计,在增加新特性时总是步履维艰,甚至有点不伦不类。

关于CE的设计,有人对Anders Hejlsberg进行过一次采访。采访的原文链接在这里:https://www.artima.com/intv/handcuffs.html

关于CE,Anders Hejlsberg认为它带来了两个问题版本问题扩展问题

所谓的版本问题是什么意思呢?Anders Hejlsberg举了一个例子:

假设有一个方法foo,它声明了抛出异常A、B和C,在下一个版本设计的时候,foo增加了一个新的特性,可能会抛出异常D。对于设计者来说,很明显这是一个大的改变,几乎可以确定的是,客户程序员不会去处理这个异常。为了避免出现问题,设计者不得不声明一个新的方法foo2,抛出一个新的异常。然后,客户程序员可以将针对foo的逻辑处理切换到foo2。

而所谓的扩展问题又是什么意思呢?这更好理解,以下来自Anders Hejlsberg的原话翻译并整理:

如果你在设计一个很小的系统,声明一个方法抛出一个异常,这很棒。可是,如果你尝试构建一个大的系统,其中包含了四、五个小系统的时候,问题来了。假设每个子系统可能抛出四到五个异常,而每上升一个系统,就犹如爬阶梯,异常数量会指数倍增加,最终你可能处理的异常将达到40个甚至80个。很显然,这是一个很糟糕的设计!

Anders Hejlsberg的话有理有据。可是,中国的 王垠 并不同意这个观点。关于Kotlin的CE设计,他写了一篇文章专门讲了这个问题,文章的原稿在这里:Kotlin 和 Checked Exception

看完王垠的文章,你会发现,他并不赞同Anders Hejlsberg的话。他认为,所谓的版本问题和扩展问题,其实都来自于程序员的滥用。只要处理得当,CE带来的好处是无法取代的。

其实,关于CE的争论还远不止Anders Hejlsberg和王垠两人。互联网上有很多关于这个问题的讨论。如果你感兴趣,可以Google了解一下。

你怎么看?

很显然,Kotlin语言受到了C#设计的影响,手起刀落,去掉了CE的设计。对于客户程序员来说,显而易见的一个改变是,你再也不能在Kotlin的方法声明中指定可能抛出的异常了。对于Kotlin语言的这种设计,你是赞成还是反对呢?

欢迎参与投票讨论

扫描下方二维码关注欧阳锋工作室,回复“CE”参与投票,或在所有文章中选择同名文章进行投票。

欢迎加入Kotlin交流群

如果你也喜欢Kotlin语言,欢迎加入我的Kotlin交流群: 329673958 ,一起来参与Kotlin语言的推广工作。

欧阳锋工作室 wechat
扫描二维码,关注欧阳锋工作室