问题 Intellij Idea提示:条件总是错误的 - 这可能是真的吗? (JAVA)


我有以下代码:

public String testExitPoints() {
    boolean myBoolean = false;
    try {
        if (getBoolean()) {
            return "exit 1";
        }
        if (getBoolean()) {
            throw new RuntimeException();
        }
    } finally {
        myBoolean = true;
    }
    if (getBoolean()) {
        return "exit 2";
    }
    return "exit 3";
}

public static boolean getBoolean() {
    Random rand = new Random();
    return rand.nextInt() > 100;
}

现在IntelliJ的想法给了我第二次和第三次调用 getBoolean() 以下提示:

Condition 'getBoolean()' is always 'false'

现在据我所知,这不是真的,因为 getBoolean() 可以是 true 要么 false,取决于生成的随机值。我在这里遗漏了什么,或者是IntelliJ Idea中的错误?


12124
2017-08-05 10:31


起源

我想不是。你要么调用另一个 getBoolean() 比你发布的,或者它是Intellij Idea中的一个错误(在这种情况下你应该提交错误报告)。运行代码时会得到什么? - Axel
没有别的 getBoolean(),它只是这种方法的测试项目。运行代码有时会返回 false and sometimes 真的,你会期待的。 - Mathias Bader
如果返回值 getBoolean()不是随机的,IntelliJ是正确的。所以我猜它确实是一个错误(读作:可能是某种不正确的优化/简化)。 - Marvin
可能是因为你的第二和第三 if(getBoolean()) 条件永远不会被执行。因为你在第一个条件下有回报。如果从第一个条件中删除return语句会发生什么? - Amit.rk3
它们会被执行,具体取决于第一个的返回值 getBoolean() 调用。 - Mathias Bader


答案:


这不是一个错误。这是一个功能:)

如果仔细查看IDE,它会告诉您对getBoolean()的第二次和第三次调用始终为false,但不是第一次。

Idea假定(在这种情况下不正确)您的方法(无参数且称为“get”...)将始终返回相同的值。

如果是这种情况,并且第一次调用是真的,则永远不会访问另一个(因为返回)。

如果第一个呼叫是假的,那么其他呼叫也是假的。

IDEA试图变得聪明w.r.t.良好的编码实践,但并非绝对可靠。

如果您更改方法以获取参数(或重命名它以使其看起来不像吸气剂)

public  boolean getBoolean(int x) {
    Random rand = new Random();
    return rand.nextInt() > 100;
}

警告将消失(即使您始终使用相同的参数调用)。

(注意,即使它是一个getter,如果它是非final字段,它仍然是错误的,因为它可能在多线程环境中发生变化!)


8
2017-08-05 10:42



有趣。那确实是一个错误 - 调用没有参数的方法并不意味着不会有副作用或不同的返回值。 - Mathias Bader
即使改变了 public static boolean getBoolean(int ... x) { 这里有诀窍(不包括更改调用的必要性)。 - Mathias Bader
@MathiasBader你是对的。我错误地解释了它:它是关于将它读作吸气剂。请参阅更新的答案(注意:它仍然是错误的,它可能在多线程环境中静音,即使作为一个吸气剂!,但在大多数情况下不应该发生)IDEA做得最好,但它并不完美。 - Diego Martinoia
太棒了 - 然后澄清了。很高兴我的直觉是正确的,这里有些不对劲。我在JetBrains提交了一份错误报告 - 感谢您的回答。 - Mathias Bader


不幸的是,虽然接受的答案给出了很好的解释,但并不总是可以重命名触发方法,因为它们可能存在于第三方代码中。例如,我使用的是MongoDB库中的first()函数,它显然可以返回null值,但是当我想测试它是否为null时会触发警告。

如果您确信IDEA错了,那就放好吧

                //noinspection ConstantConditions

在导致问题的声明之前。

一般来说,一个方便的选项是“分析”菜单下的“检查代码...”。在那里,您可以查看整个项目,或仅查看您关注的文件。您可能会发现比您讨价还价更多的关注领域!问题中的警告将列在“可能的错误”下。注意“可能” - IDEA知道它不是绝对可靠的:)


2
2017-07-29 11:15





IDEA认为 getBoolean()当第二次(或第三次)调用时,调用不会被更改。通常,如果返回相同的值,则永远不会实现第二次调用。这就是IDEA强调它的原因。


1
2017-08-05 10:40





在我的情况下,如果我使用MY_ACTUAL_CLASS_NAME.getBoolean(),它不会抱怨(因为该方法是静态的)。可能是因为IntelliJ Idea没有考虑静态(这里可能存在错误)


0
2017-07-07 18:21