Kotlin删除检查的异常背后的想法是什么?

时间:2019-10-31 08:08:32

标签: exception intellij-idea kotlin checked-exceptions

当我们在Java中调用抛出异常的方法时,如何处理呢?

我的代码在kotlin中,我正在使用用Java编写的第3方库。我调用该库的方法,在某些情况下,该方法会引发一些自定义异常。现在,kotlin不会强制我处理此类异常,在这种情况下,应用程序将崩溃。处理此问题的最佳方法是什么?

1 个答案:

答案 0 :(得分:2)

当Java引入了检查异常(编译器强制大多数异常被捕获或声明为抛出)时,这是一个相当新的想法。 Java是比其大多数前代产品更为安全的语言:在所有平台上定义并一致的所有行为,以及旨在防止崩溃,意外行为或易碎编码的许多功能。因此,检查异常符合该语言的哲学。

但是从那以后的几年中,许多人得出结论,检查异常是一个错误。我并不完全相信,但这是其中一些原因:

  • 它们很冗长。方法通常包含许多trycatch块和/或声明许多异常。另外,如果在引发异常和捕获异常之间有6种方法调用级别,则该异常将需要由5种方法声明。

    Kotlin取消了Java的大部分样板,并且消除了已检查的异常。

  • 他们鼓励不良做法

    • 试图在错误的地方(即错误的抽象级别)处理异常,在此情况下无法执行任何有用的操作。
    • 毫无意义的catch块(尤其是危险的块,除了记录错误外什么也不做)。
    • 捕获/声明Exception而不是特定的子类型。
    • 通过将检查的异常包装在未检查的异常(例如RuntimeException)中来作弊。
  • 它们会增加模块之间的耦合。。如果您使用的库方法添加了新的异常,则需要更新所有调用该方法的代码以处理或重新抛出该异常。 / p>

  • 它们要求在不同抽象级别之间转换异常。 (例如,数据库访问层可能必须将套接字超时异常转换为数据库不可用的异常。)这很繁琐,但是必须避免公开实现细节。

  • 它们不能很好地继承。如果没有声明要实现/重写的方法抛出特定的已检查异常,则您的实现将无法抛出该异常。要么。

  • 它们不适用于lambda。。在Java中,lambda是使用Single-Abstract-Method接口实现的,因此这些方法必须声明可能的异常(在这种情况下)每次使用都必须处理或声明它),否则lambda主体必须捕获异常。这两种选择都极大地增加了概念上的重量以及使用lambda所需的代码,破坏了简洁性,这是它们的主要优点之一。

    Kotlin的实现非常相似(尽管它使用自己的KFunction接口),并且会遇到相同的问题。

对于所有这些问题,很明显,检查异常是充其量的祝福。而且我知道为什么Kotlin放弃了它们。

我确实担心,这可能会导致程序的健壮性降低(并且文档记录不充分)。但是在我使用Kotlin的两年中,我还没有看到任何明显的案例。所以我暂时暂缓判断:-)

(另请参阅this问题。)


关于如何处理您的特殊情况,我建议您采取与Kotlin检查异常的方式相同的方法:查看您所调用的方法可以抛出哪些异常,确定如何/在何处最佳地处理它们,并处理它们!仅仅因为Kotlin不会强迫这样做,并不意味着它仍然不是一个好主意!