SonarQube错误:重构这个方法抛出最多一个检查异常

问题描述:

我使用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个例外,我定义说例如Exception1Exception2延伸Exception。而我的方法说,sampleMethod()抛出他们即,

public void sampleMethod() throws Exception1, Exception2 { 
} 

,并在此处显示的错误。所以我应该有一个类作为父母(说MainException)并从它派生Exception1Exception2并抛出父异常类?如下所示:

public void sampleMethod() throws MainException { 
} 

上述解决方案是否正确?

+1

听起来像是你的情况的解决方案:D或你为这种方法提供了一个专用的例外,它提供了一点点的信息 –

+0

我有几个项目的SonarQube抱怨有同样的“重大”错误。在与我的办公室中的一对中小企业交流之后,两家学校都有倡导者和反对者。我的意见是创建一个''MainException''父类,如你所说,并使SonarQube高兴。 – Jeremy

IOexception和sqlexception都是检查异常s,彼此完全不同,现在如果我们从一个异常扩展两个异常并抛出父异常,这在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将然后将被包括在抛出具有这种尝试捕捉方法签名的子句。

DataException扩展了Exception类,并且通过在构造函数中传入ex,将原始异常封装在自定义异常中,同时保留原始异常信息。

+0

感谢您的回复。你可以给出一个示例/伪代码如何将它们封装在catch块中的基于定制的异常中。对不起,因为我是新的,我完全不明白 – pgman

+0

我已经编辑了我的答案,incooperate的例子,希望其明确 – pndey

如果您的应用程序中有一个声明为throws SQLException, IOException的方法,那么您可能会将内部实现细节泄露给方法的用户。具体而言,您的意思是:

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

  2. 你的方法,包括它的任何未来版本,永远不会抛出任何其他检查异常。如果将来你改变你的方法,这样它可能会抛出另一个检查的异常,它会打破向后兼容性。

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

但是,请注意,有一个思想流派说Java checked exceptions are a bad idea(以及C#没有检查异常的原因之一)。