【问题标题】:How to avoid magic number warning when initialize static field (for example BigDecimal)?初始化静态字段(例如 BigDecimal)时如何避免幻数警告?
【发布时间】:2019-01-03 01:27:20
【问题描述】:

我有静态字段

private static final BigDecimal MAX_AMOUNT = BigDecimal.valueOf(299_999L);

我收到 CheckStyle 的警告,299_999L 是幻数。 我怎样才能避免这种情况 - 299_999 只是长转换为指定的BigDecimal

我在 CheckStyle 文档中没有找到任何合适的解决方案。

编辑: 例如,当我输入时它就会出现:

private static final BigDecimal MAX_AMOUNT = BigDecimal.valueOf(299_999L).setScale(4, BigDecimal.ROUND_HALF-EVEN)

【问题讨论】:

  • 有趣!我无法重现这种行为。您使用的是哪个版本的 Checkstyle?您可以分享 checkstyle.xml 中的 MagicNumber 配置吗?根据docs,您不应该收到此警告。
  • 太糟糕了。当我输入 BigDecimal.valueOf(299_999L).setScale(4, BigDecimal.ROUND_HALF-EVEN);

标签: java initialization field bigdecimal checkstyle


【解决方案1】:

有趣的是,您在声明静态字段时遇到此错误。但是,无论您如何添加 suppresswarning 注释,

@SuppressWarnings("checkstyle:magicnumber")

【讨论】:

    【解决方案2】:

    在您澄清评论之后,我可以说警告的原因在于 MagicNumber 检查的工作方式。 如果潜在的幻数在字段定义中,并且该字段是final,那么只要 AST 中的所有父令牌直到表示字段定义的节点在某个列表中。

    这很令人困惑,我认为对于普通用户来说,这似乎是任意的。但是静态代码分析通常是关于启发式的。

    好消息是你可以影响这种行为。像这样配置检查:

    <module name="MagicNumber">
        <property name="constantWaiverParentToken"
            value="TYPECAST, METHOD_CALL, EXPR, ARRAY_INIT, UNARY_MINUS, UNARY_PLUS, ELIST, STAR, ASSIGN, PLUS, MINUS, DIV, LITERAL_NEW, DOT"/>
    </module>
    

    constantWaiverParentToken 的值是默认的 DOT 添加到末尾。这允许更复杂的表达式。您至少需要 Checkstyle 6.11 才能正常工作。

    【讨论】:

    • 需要注意的是constantWaiverParentToken没有考虑到被调用的方法,所以它会隐藏方法改变常量值或者方法调用中有多个常量的违规行为.
    【解决方案3】:

    您必须声明一个常量来描述该值的更多含义:

    private static final Long MAX_AMOUNT_INITIALIZER = 299_000L;
    private static final BigDecimal MAX_AMOUNT = BigDecimal.valueOf(MAX_AMOUNT_INITIALIZER);
    

    这听起来有点多余,但请记住,幻数是代码中使用的任何数字,但对其含义没有任何解释。即使您有一个 BigDecimal 常量,您的 Long 值也不会被解释为上下文的“有意义的值”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      • 2021-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-15
      相关资源
      最近更新 更多