【问题标题】:SonarQube error - Throwing a dedicated exception instead of generic exception for an Abstract classSonarQube 错误 - 为抽象类抛出专用异常而不是通用异常
【发布时间】:2019-03-15 06:57:04
【问题描述】:

我正在清理 SonarQube 问题,其中一个错误抱怨:定义并抛出一个专用异常,而不是使用通用异常。

public abstract class Message {

    public abstract byte[] getPayload() throws Exception;

    public abstract Optional<String> getStringMessage() throws Exception;

}

由于这是人们用作 API 的库中的一个类,以及人们继承的抽象类,我不确定将其更改为引发专用异常是否会影响其他服务,因此不好。任何建议、方向、答案将不胜感激!

【问题讨论】:

  • 需要考虑两件事:使用和扩展。对于使用来说,这不会是一个问题,因为用户可能已经捕获了一个通用异常(这仍然是一种可怕的做法,但无论如何),所以如果你有一个自定义异常,他们的 catch 子句仍然可以工作。但是,对于扩展您的课程的人,他们的实现将被新代码破坏,因为新签名不匹配。抛出一个通用异常是个坏主意,但现在你不能在不破坏某些东西的情况下修复它
  • 感谢亚瑟的建议!我可能会跳过这个错误,但只是好奇,新签名不匹配是什么意思?
  • 想象一个开发者在他的代码中有你的库(一个依赖)。由于某些原因,他想扩展Message 类。所以他重写了getPayloadgetString 方法(因为他想这样做)。他的代码运行良好。现在,您发布了新版本的代码,这些方法带有自定义异常。如果他只是简单地升级他的依赖项,他将有一个编译错误,说他的覆盖函数与原始函数不匹配(因为现在,它必须抛出 CustomException 而不是 Exception)。这就是我们所说的重大变化
  • 哦,我明白你的意思了。谢谢你:)

标签: java exception


【解决方案1】:

不要在检查Message 的扩展类型抛出了哪些Exceptions 之前更改抛出的Exception。您可能会破坏现有代码(见下文)。

如果每个扩展类型都没有使用更具体的Exception,那么,您必须将其替换为更清晰、更惯用的类型。

自定义Exception 可以携带附加数据作为类字段。这些额外的数据可以设置在投掷点(通常是只有该数据可用的地方),并在处理时在上层进行检查。

由于该类充当某种interface(考虑将其重构为interface,确实如此),它将是随处暴露/使用的类,因此它需要尽可能清晰。

几个可能的名字可能是

MessageException
PayloadRecoveryException

应用更具体的Exception,具有已经提供特定类型的扩展类型,甚至只是基Exception,将导致编译错误

起点

现在,将Exception 升级为“自定义”。 错误

所以要小心,否则会有人抱怨。

【讨论】:

  • 谢谢!我将看看这些方法的用法。关于将其重构为界面,它是否也会影响其他团队?我假设到目前为止,人们将扩展抽象类,但如果我将其更改为接口,他们必须实现它。我想我必须让其他团队知道这次重构。另外,您推荐接口而不是抽象类的原因是什么?抱歉,这可能问题太多了,我想学习:)
  • @louprogramming 是的,它将影响该定义的每个用户。接口本身只是一个类,其所有方法都标记为抽象。但是,类可以实现多个接口,而只能扩展一个类。您基本上是在这方面限制您的用户。同样,接口不能单独携带数据,而抽象类可以,并且不能提供方法实现,而抽象类可能会。接口也是公开 API 时的事实标准
猜你喜欢
  • 1970-01-01
  • 2016-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-24
  • 1970-01-01
  • 2018-03-23
相关资源
最近更新 更多