为什么SQLException是一个经过检查的异常

时间:2013-05-14 12:47:40

标签: java exception coding-style checked unchecked

有人会想到SQLException已检查例外的理由吗?

是的,查询中可能存在语法错误 是的,连接可能已经死亡了 是的,可能存在许可问题 等等等等等等等等等等

但实际上100%的时间(一旦你在生产中运行),没有任何问题。

如果出现问题,调用代码无法执行任何恢复,因此应该取消选中

正在检查中,在整个代码中创建大量的敷衍try catch块,因为任何参与使用JDBC的项目的人都会证明。代码混乱很重要。

由于SQL的深奥性质,你可能得到SQLException及其复杂性的原因很多,这意味着你基本上无法恢复,除非异常是由临时网络问题引起的,但即便在同步调用中,你也是无论如何都要沉没,因为你无法无限期地等待解决网络问题,所以你将不得不使交易失败。

通常,调用SQL看起来像这样:

try {
    // make some SQL call(s)
} catch {SQLException e) { 
    // log the exception
    return; // and give up
}

此类代码不会增加值。没有什么合理的你可以恢复。您也可以让运行时异常冒泡 - 即SQLException应该是运行时(未经检查)异常。

4 个答案:

答案 0 :(得分:2)

几乎100%的时间没有任何问题 - 这仅限于您自己的观察结果对任何其他系统一无所知。世界各地有各种计算机系统存在各种瓶颈。你的成功率几乎是100%。其他人必须处理更低的百分比。

常见的误解是考虑通过频率引入/删除Checked Exception。已检查的例外充当沟通渠道。如您所知,每种方法都有其公共接口。这样,方法告诉我们它接受哪些参数以及它体内代码的结果是什么。

当一个当前正在进行的方法无法保持其承诺(例如返回值)时,它需要一种方法来告诉另一种方法出错的地方并且它不能做到预期的事情。但怎么办呢?将消息作为返回的值发送不起作用,调用方法几乎没有机会区分正确的值和错误消息。不是说某些方法作为返回值而无效。那么当你无法保持你方法界面定义的承诺时,你会怎么做?好吧,你抛出异常(发送消息)。

如果您期望ResultSet并且建立的数据库没有连接,您应该怎么做?返回空ResultSet?不,这告诉我们数据库是空的。返回null?嗯,这只是代表问题并且找不到原因。

您可以使用该空结果集并将其作为另一个查询到另一个数据库的一部分,使其不一致。

如果没有SQLException,即使一个错误也可能导致数据不一致。

答案 1 :(得分:2)

捕获异常使我们能够从异常条件中恢复,这是真的,但它们也允许我们做其他事情。

您无法从SQLException中恢复,因为您无法在运行时解决问题,但您可以执行一些有用的操作:

  • 记录调试信息的异常
  • 回滚交易

您总是可以将异常记录在更高级别(或更低级别,具体取决于透视图),但是在调试时和查看代码时都会丢失一些语义值。

如果您执行以下操作:

try { ... }
catch(SQLException e) 
{ 
    SomeLogger.log(...);
    rollback();
    throw e;
}

稍后回到此代码,您将立即意识到try中的代码可能会失败,而无需在心理上解析代码以确定它是否可能失败。

您可以做的另一件事是确保已发布任何数据库资源,但我不确定这是否可能发生。

答案 2 :(得分:1)

检查与未经检查的困境有两种方法。检查调用代码是否可以从异常中恢复是一种方法,但是,我同意这一方法并不能解释为什么SQLExcption已检查异常。

Martin Fowler在他的伟大着作“重构”中提供的另一个建议验证是否调用调用方法负责进行检查导致例外。

如果调用者方法在调用调用方法之前应执行检查(例如确保参数不为空),那么如果没有进行此检查显然是编程错误,然后调用方法会抛出未经检查的异常。

现在,如果调用方法负责进行检查,因为只有这个方法可以知道如何执行此类检查,那么从调用方法抛出的异常应该被检查

如果是SQLException,我认为只有这个班级才能知道:

  • 查询中存在语法错误,因为这取决于数据库
  • 连接已经死亡
  • 存在权限问题

答案 3 :(得分:1)

一个原因是方法应该抛出异常,这与该方法的抽象级别一致。

因此,从数据库加载信息的方法不应该引发SQLException,而应该引发ResourceNotFoundExceptionResourceUnavailableException

使SQLException检查是强制开发人员捕获异常并将其包装在这个新的抽象级别中的一种方法。

该论点取自Joshua Bloch的Effective Java Second Edition(第61项:抛出适用于抽象的例外)。