Java 为什么SQLException是选中的异常

Java 为什么SQLException是选中的异常,java,exception,coding-style,checked,unchecked,Java,Exception,Coding Style,Checked,Unchecked,有人能想出一个合理的理由来解释为什么是检查异常吗 是的,查询中可能存在语法错误 是的,连接可能已断开 是的,可能存在权限问题 诸如此类诸如此类诸如此类 但实际上,100%的时间(一旦投入生产),都没有任何问题 如果出现问题,调用代码将无法执行任何恢复操作,因此应取消选中它 被检查会在整个代码中创建大量敷衍的try-catch块,任何参与过使用JDBC的项目的人都会证明这一点。代码混乱非常严重 由于SQL的深奥本质,您可能会得到SQLException的无数原因及其复杂性意味着您基本上无法恢复,除

有人能想出一个合理的理由来解释为什么是检查异常吗

是的,查询中可能存在语法错误
是的,连接可能已断开
是的,可能存在权限问题
诸如此类诸如此类诸如此类

但实际上,100%的时间(一旦投入生产),都没有任何问题

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

被检查会在整个代码中创建大量敷衍的
try-catch
块,任何参与过使用JDBC的项目的人都会证明这一点。代码混乱非常严重

由于SQL的深奥本质,您可能会得到SQLException的无数原因及其复杂性意味着您基本上无法恢复,除非异常是由临时网络问题引起的,但即使在同步调用中,您也会失败,因为您不能无限期地等待网络问题得到解决,因此,你将不得不使交易失败

通常,调用SQL如下所示:

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

这样的代码不会增加任何价值。没有什么合理的办法可以恢复。您还可以让运行时异常冒泡——ie SQLException应该是运行时(未选中)异常

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

马丁·福勒(Martin Fowler)在其著作《重构》(Refactoring)中提供的另一个建议是,验证是调用还是被调用的方法负责进行可能导致异常的检查

如果调用方方法应在调用被调用方法之前执行检查(例如,确保参数不为null),则如果未执行此检查,则显然是编程错误,然后被调用方法应引发未检查的异常

现在,如果检查是被调用方法的责任,因为只有这个方法才能知道如何执行这样的检查,那么应该检查从被调用方法抛出的异常

SQLException
的情况下,我认为只有这个类可以知道:

  • 查询中存在语法错误,因为这取决于数据库
  • 连接已断开
  • 有一个权限问题

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

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

选中
SQLException
是一种迫使开发人员捕获异常并将其包装到新的抽象级别的方法

此论点摘自Joshua Bloch的《有效Java第二版》(第61项:抛出适用于抽象的异常)。

几乎100%的时间没有任何问题-这仅限于您自己的观察,对其他系统没有任何说明。世界上有各种各样的计算机系统,有各种各样的瓶颈。你的成功率几乎是100%。其他人则必须处理低得多的百分比

<强>常见错误概念是考虑通过<强>频率>引入/删除检查异常。选中的异常用作通信通道。正如您所知,每个方法都有其公共接口。通过这种方式,方法告诉我们它接受哪些参数,以及它的主体中的代码的结果是什么

当当前正在进行的方法不可能遵守其承诺(例如返回值)时,它需要一种方法来告诉另一个方法出了问题,并且无法执行预期的操作。但是怎么做呢?当返回的值不起作用时发送消息,调用方法几乎没有机会区分正确的值和错误消息。并不是说有些方法将void作为返回值。那么,当您无法遵守由方法接口定义的承诺时,您会怎么做?嗯,您抛出了一个异常(发送消息)

如果您希望使用ResultSet,但没有建立到数据库的连接,您应该怎么做?返回空结果集?不,这告诉我们数据库是空的。返回空值?好吧,这只是代表了问题,使寻找原因变得不清楚

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


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

捕获异常可以让我们从异常情况中恢复,这是事实,但它们也允许我们做其他事情

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

  • 记录异常以获取调试信息
  • 回滚事务
您可以始终在更高的级别(或更低的级别,取决于透视图)记录异常,但无论是在调试时还是在查看代码时,都会丢失一些语义值

如果您执行以下操作:

try { ... }
catch(SQLException e) 
{ 
    SomeLogger.log(...);
    rollback();
    throw e;
}
稍后再回到这段代码,您将立即意识到,try中的代码可能会失败,而不必在心里解析代码以确定它是否会失败

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

A)网络、数据库服务器、负载平衡器等没有100%的正常运行时间B)发生故障时,您肯定可以做些什么。服务器