【问题标题】:SonarLint warning, this code will always return the same valueSonarLint 警告,此代码将始终返回相同的值
【发布时间】:2018-09-22 07:24:48
【问题描述】:

SonarLint 告诉我:

"Refactor this code to not always return the same value."

但我似乎不明白为什么

private List<InvoiceRejectionMessage> invoiceList = new ArrayList<>();

public String getMessage() {
    if(!invoiceList.isEmpty()) {
        return invoiceList
                .stream()
                .max(comparing(InvoiceRejectionMessage::getCreatedAt))
                .get()
                .getMessage();
    }
    return null;
}

InvoiceList 已定义并且将始终被初始化,因此它不能为空,只能为空。如果为空,则返回 null。如果不是,我们确定其中有一个元素可以由 .max() 和 .get() 返回

我不愿意仅仅因为 Sonarlint 告诉我重构这个方法,我宁愿知道为什么我会收到这个警告

【问题讨论】:

  • invoiceList 已初始化,但它是一个空数组。你从来没有.Add() 什么东西给它。因此.isEmpty() 将返回true,您的函数将返回null
  • @RonNabuurs 它检查代码库的其余部分是否有 .add()?
  • 如果我使用 Sonarlint 将 sn-p 复制粘贴到我的 Intellij 中的测试项目中,即使我没有调用 .Add(),我也不会收到错误消息。也许这是某个地方的设置。恐怕我也不知道。
  • 文体问题:为什么返回不返回Optional&lt;String&gt; 而不是“可空”String
  • @Jubobs 目前它唯一的用途是在我宁愿保持清洁的 DTO 中;例如dto.setInvoiceMessage(invoice.getMessage)

标签: java-8 optional sonarlint


【解决方案1】:

与此提示关联的规则是

squid:S3516 - 方法返回不应该是不变的

此规则的 SonarQube 实现在 GitHub 上可用。

如果没有看到您的代码整体,我不能 100% 确定为什么会触发此规则。但是,我怀疑声纳能够弄清楚

  1. invoiceList 无条件为空并且;因此
  2. if-then-else 语句的if 分支永远不会被执行;因此,
  3. the getMessage 方法无条件返回null

无论如何,没有必要将空列表视为特殊情况;您可以通过以下方式简化代码,这可能会安抚 Sonar:

private List<InvoiceRejectionMessage> invoiceList = new ArrayList<>();

public String getMessage() {
    return invoiceList
            .stream()
            .max(comparing(InvoiceRejectionMessage::getCreatedAt))
            .map(InvoiceRejectionMessage::getMessage)
            .orElse(null);
}

顺便说一句,如果您可以更改类的 API,它的客户端将受益于将 getMessage 的返回类型更改为 Optional&lt;String&gt;(只需删除最后一个 orElse(null) 调用):

public Optional<String> getMessage() {
    return invoiceList
            .stream()
            .max(comparing(InvoiceRejectionMessage::getCreatedAt))
            .map(InvoiceRejectionMessage::getMessage)
}

【讨论】:

  • 这确实是平静的声纳,它看起来更干净。我仍然想知道为什么 Sonar 认为它是“错误的”
  • 抱歉应该提到这一点:squid:S3516 与 squid:S3655 结合(它希望我在 .get() 之前调用 isPresent ,我理解但它没有用,因为它不会为 null 或当我们到达语句时为空)。可能是两者的结合导致 Sonar 认为它比实际情况更糟?
  • @Laurens 我已经扩充了我的答案。甚至 Sonar 也正确地指出 Optional#get 需要小心,the isPresent-get idiom is considered bad practice;其实这里可以避免。
  • 您没有专门解决我的问题,但您的回答简洁明了,我会将其标记为已解决,并将其归结为 Sonarlint 的一个小问题
猜你喜欢
  • 2021-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-26
  • 2020-11-04
  • 2019-06-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多