【问题标题】:Correctly formulate conditions for constants?正确地制定常数的条件?
【发布时间】:2019-06-15 13:20:49
【问题描述】:

我的项目中有一个常数,它代表了一些时间跨度。当它低于 0 时,我想禁用时间跨度相关检查。

通常会检查

if(CONSTANT > 0) foo();
else bar();

但这会导致警告“条件始终为‘假’”或“条件始终为‘真’”,具体取决于常量的值。

有没有办法绕过这个警告,以防止另一个开发人员只做那几行?


编辑: 我的问题有点太笼统了。对于那个很抱歉。

我有一个计时器,经过一段时间 TIME_FOR_AUTH(常量)后,我的模型将被清除。这是一种安全措施,会在测试时产生问题。因此,我在我的代码中添加了一个检查 if(TIME_FOR_AUTH > 0) ...

现在我得到了描述的警告。由于 IntelliJ 总是要求我删除这个结构(在这个项目中我并不孤单),我想知道在 Java 中是否有一种常见的做法/有可能抑制警告。

【问题讨论】:

  • 常量不会改变(这不是你收到警告的原因),否则你误用了这个概念。
  • @lealceldeiro 我知道,运行代码中的常量不会改变。但是我正在使用描述的那个来启用(或禁用)我的程序中的计时器,并使用它设置时间。我不确定还有什么其他概念可以用于此。
  • 您的问题不清楚,正如您所问的两个答案之间的“辩论”所示!请阅读这些答案,然后澄清您的问题,以便人们了解您的实际问题。请通过编辑问题来澄清...

标签: java compiler-warnings compile-time-constant


【解决方案1】:

起初,这只是一个警告。

其次,您可以使用@SuppressWarnings 注释来抑制警告。对于“始终为真/假”的警告,应为 @SuppressWarnings("ConstantConditions")

代码示例:

package stackoverflow;

public class SuppressWarningsExample {

    @SuppressWarnings("ConstantConditions")
    public static void main(String[] args) {
        final int value = 100;

        if (value > 0)
            System.out.println("Yes");
        else
            System.out.println("No");
    }
}

对于 IntelliJ IDEA,您还可以使用内联 // noinspection <InspectionName> 注释抑制每个表达式的警告:

// noinspection ConstantConditions
if (value > 0)
    System.out.println("Yes");
else
    System.out.println("No");

【讨论】:

  • 我实际上认为这个问题是关于当你有意识地知道表达式是恒定的(你通常这样做是为了暂时排除一些代码。例如,我有时做if (true) { doSomething(); return;},在一些复杂的调试中只执行部分方法而无需大幅更改代码),并摆脱烦人的警告。在问题的文本中,相同的目标非常明确地定义为“防止另一个开发人员仅执行该行”,例如暂时只执行代码的一部分而不删除其余的方法代码。
  • 当然这只是一个警告,但它总是建议我删除那段代码;)而且我不知道这些可以很容易地被抑制。谢谢
  • 是的,我了解删除建议的问题。请注意,您还可以在 IDEA 中添加@SuppressWarning,几乎可以在有问题的表达式上使用 Alt + Enter → 在“Unwrap 'if' statement”选项上按 Right → 选择一些“Suppress for .. ." 动作。
【解决方案2】:

这里:

if(CONSTANT > 0) foo();

你自己说。它是一个常数。因此,从一开始,它要么大于0,要么小于0。因此编译器兴高采烈地把上面的变成:

if(...x... > 0) foo();

其中x 将是您分配给CONSTANT 的实际值。所以就在那里,在编译时,这变成了

if (true)

或者if (false)

长话短说:重新思考你在做什么。可能你不应该比较你的常数,而是像:

LocalDateTime endTime = LocalDateTime.now().plusHours(1);

然后,稍后:

if (LocalDateTime.now().isAfter(endTime)) {

或类似的东西。

换句话说:比较一个常量值来识别某个条件根本没有多大意义。相反,您可以使用常量来计算一些“结束时间”,然后随着时间的推移检查当前时间与该“结束时间”。尤其是在使用像 LocalDateTime 这样的类时,计算一个稍后的时间戳非常容易,如上所示。

编辑,考虑到问题的编辑:我仍然建议不要在生产代码中使用这样的构造。相反,我会研究使测试设置能够以一种允许其有效禁用这种超时机制的方式配置生产的方法。例如,通过注入一个保证在合理的测试执行时间内不会被命中的超时!

【讨论】:

  • 这是个好主意,谢谢。遗憾的是它不适合我的具体问题,但我会记住它以备后用。
猜你喜欢
  • 2021-04-06
  • 1970-01-01
  • 2017-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多