SonarQube 错误:重构此方法以引发最多一个已检查的异常



我正在使用SonarQube,它显示以下错误:

Public methods should throw at most one checked exception.
// Noncompliant
public void delete() throws IOException, SQLException { /* ... */ }
// Compliant
public void delete() throws SomeApplicationLevelException { /* ... */ }

这是否意味着,SomeApplicationLevelException是父类,IOExceptionSQALException都是从它派生的?我们应该抛出父类异常吗?从而坚持方法仅抛出 1 个已检查的异常?

因为我有 2 个我定义的例外,例如Exception1和扩展ExceptionException2。我的方法说,sampleMethod()扔它们,即,

public void sampleMethod() throws Exception1, Exception2 {
}

错误显示在此处。那么我应该有一个类作为父类(比如MainException)并从中派生Exception1Exception2并抛出父异常类吗?如下所示:

public void sampleMethod() throws MainException {
}

上述解决方案是否合适?

如果您的应用程序中有一个声明为throws SQLException, IOException的方法,则可能会向方法的用户泄露内部实现详细信息。具体来说,你是说:

  1. 您的方法是使用 JDBC 和文件 I/O 实现的。您的用户并不关心您的方法是如何实现的;他们只关心你的方法做了什么。

  2. 您的方法(包括它的任何未来版本)永远不会引发任何其他已检查的异常。如果将来更改方法,以便它可能引发另一个已检查的异常,它将破坏向后兼容性。

建议是创建自己的特定于应用程序的类(派生自 Exception),并且只在方法中抛出它。如果您愿意,可以将 SQLException 或 IOException(或任何其他异常)包装在特定于应用程序的异常中作为原因

但是请注意,有一种思想流派认为 Java 检查异常是一个坏主意(这也是 C# 和更现代的语言(如 Kotlin )没有检查异常的原因之一)。

更新:上述答案与问题的第一个版本有关(编辑#1)。该问题随后进行了更新,指出抛出的两个异常是应用程序定义的异常,因此上述大部分理由不再适用。这篇文章解释了更新问题的答案。

IOexception和sqlexception都是检查异常,彼此完全不同,现在如果我们从一个异常扩展两者并抛出父异常,这在java中不是强制性的,这将有点误导API的用户。

但是,如果您想在应用程序中执行此操作以避免 sonarqube 错误 ,您可以捕获所有特定异常并抛出自定义异常,将原始异常信息包装在异常消息中。

例如

try{
///piece of code that throws IOException and SQLException
}catch(IOException | SQLException ex){
throw new DataException(ex,"Any customized message you want");
}

然后,此数据异常将包含在具有此尝试捕获的方法签名的抛出子句中。

DataException 扩展了异常类,通过在构造器中传递 ex,您将原始异常包装在自定义异常中,并保留原始异常信息。

相关内容

  • 没有找到相关文章

最新更新