【问题标题】:Remove the literal "false" boolean value删除文字“假”布尔值
【发布时间】:2022-01-07 20:34:06
【问题描述】:
 public List<LawOfficeDetailEntity> getLawOfficeByManagementUnitId(Long managementUnitId, Boolean statusless) {
        List<LawOfficeDetailEntity> entities = lawOfficeDetailRepository.findByManagementUnitType(String.valueOf(managementUnitId));
        return (statusless == null || statusless == false) ? entities.stream().filter(office -> office.getValidityStatus() == 1).collect(Collectors.toList()) : entities;
    }

我在无状态 == false 上有“删除文字“假”布尔值”声纳错误。我该如何解决?

【问题讨论】:

  • !statusless替换statusless == false
  • 您是否阅读过Sonar 是如何解释问题的? rules.sonarsource.com/java/RSPEC-1125
  • sonarqube 不也对它发现的问题给出解释(带有示例)吗?

标签: java spring spring-boot sonarqube


【解决方案1】:

鉴于这个问题是关于 linting 工具的,因此严格来说是关于正确的代码风格和卫生,因此这个问题有点棘手:是的,有一种方法可以“避免声纳警告”,但这就像把火箭筒交给孩子:使用声纳的唯一原因是编写正确的代码,而“避免声纳警告”的最快、最简单的方法会使您的代码变得更糟

所以,我最好解释一下这段代码的真正问题!

--

潜在的问题是你已经将布尔值变成了三元状态:它可以是truefalseOR null,这仅在 SQL 中有意义感觉:null 表示未知、不适用或尚未设置。在所有 3 个这样的情况下,将 null 视为 false 是完全错误的。

是什么让无状态成为null?修复它。让它不是那样。如果这是您从另一个系统获得的东西,请在另一个系统中修复它(例如:如果这是一个可为空的 BOOLEAN db 列,则给它一个非空约束和一个FALSE 默认值),或者如果你不能在其他系统中修复它,一旦数据到达代码的“您的身边”,立即修复它。

一旦你完成了所有这些,statusless 成为null 的可能性就消失了。

注意:除非你完全理解它给你的每一个警告,否则像声纳这样的 Linting 工具是一个非常糟糕的主意。 linting 工具往往会发现代码的中低级问题,并且很少能检测到代码的高级、更重要的问题,就像这里的情况一样。

如果你想以某种方式忽略这个建议,因为你已经确定继续使用一个说谎的变量('boolean',甚至 'Boolean',相当强烈地建议 2 个状态,或者可能 2 个状态 + 保持未设置的能力,但肯定不是“三种状态”)无论如何都是正确的,您可以简单地将statusless == null || statusless == false 替换为:!Boolean.TRUE.equals(statusless)Boolean.TRUE 报告 false 除非您传递 true 值 - 所以无论 statuslessfalse 还是 null - 无论哪种方式,TRUE.equals(that) 都将返回 false。将false 翻转为true,瞧。

你不能写!statusless,因为如果statusless 为空,那会抛出一个NPE。

但是等等!替代解释!

也许 Boolean 确实应该代表“此值是真或假,或尚未设置/不适用于这种情况”的边界可接受概念,在这种情况下,NPE 正是你想在这里:你无法确定是否通过有效状态过滤,但你必须在这里,因此这段代码无法继续,错误在于调用者在调用此方法之前设置了无效状态。在那种情况下,你真的只想要return !statusless ? ... : ...;

【讨论】:

  • "在那种情况下,你真的只是想要" 在这种情况下最好将参数设为boolean;那么你并没有隐瞒这样一个事实,即如果传递了一个空值,这个方法抛出一个 NPE。如果将参数设置为布尔值,则拆箱发生在调用者的代码中,而不是此代码中,这清楚地表明了要避免谁的责任。
  • 是的,如果它作为参数传入,一定要小写。
【解决方案2】:

当您使用Boolean 而不是原始类型boolean 时,您不应将其与== 进行比较。你可以做的是:statusless == null || !statusless.booleanValue()

【讨论】:

  • 即使!Boolean.TRUE.equals(statusless) 也应该可以工作。
  • "你不应该将它与 ==" 进行比较,只有当你将它与 另一个 非原始比较时才会出现这种情况。因为它与false 进行比较,所以statusless 被取消装箱,== 是正确的。
  • @AndyTurner 从更广泛的角度来看,拥有三态“布尔值”绝对是不正确的。将问题简化为“让声纳闭嘴”,您的建议可以归结为“闭上眼睛,忽略警告”?那是..不是OP要求的。声纳警告不是关于将装箱值与== 进行比较的风险——它只是关于布尔比较中的冗余x == true / x == false;声纳希望你改写x / !x。因此,从问题的两个意义上来说,== 这里肯定是不正确的。
  • @rzwitserloot 我评论的是这个答案,而不是问题。
  • @AndyTurner 是的,它可以工作,但编译器必须将其拆箱。这没什么大不了的,但我认为 SonarQube 会将其突出显示为代码气味,用于不必要地拆箱布尔值。所以为了修复代码异味,你会得到另一个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-11
  • 2022-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多