Intellij Idea hint: Условие всегда неверно - может ли это быть здесь? (Ява)

У меня есть следующий код:

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?

Ответ 1

Это не ошибка. Это особенность :)

Если вы внимательно посмотрите в своей среде IDE, он скажет вам, что второй и третий вызов getBoolean() всегда являются ложными, но не первыми.

Идея предполагает (в данном случае неправильно), что ваш метод, будучи без параметров и называется "get"..., всегда будет возвращать одно и то же значение.

Если это так, и первый вызов был правдой, другой никогда не будет доступен (из-за возврата).

Если первый вызов был ложным, это были бы другие.

IDEA пытается быть умным по отношению к хорошим правилам кодирования, но это не является непогрешимым.

Если вы измените свой метод на наличие параметров (или переименуйте его, чтобы он не выглядел как геттер)

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

Предупреждения исчезнут (даже если вы все время ссылаетесь на один и тот же аргумент).

(Обратите внимание, что даже если это был getter, если он для нефинального поля все еще не так, как это может измениться в многопоточной среде!)

Ответ 2

IDEA считает, что getBoolean() не изменяется, когда он вызвал второй (или третий раз). Обычно, если вы возвращаете то же значение, второй вызов никогда не может быть достигнут. Именно поэтому ИДЕЯ подчеркивает это.

Ответ 3

К сожалению, хотя принятый ответ дает хорошее объяснение, не всегда можно переименовать триггерные методы, поскольку они могут находиться в стороннем коде. Например, я использовал функцию first() из библиотеки MongoDB, которая явно могла бы вернуть нулевое значение, но вызвала предупреждения, когда я захотел проверить его на отсутствие.

Если вы уверены, что IDEA ошибается, просто поставьте

                //noinspection ConstantConditions

перед выражением, которое вызывает проблему.

В общем, удобный вариант, о котором нужно знать, это "Проверить код..." в меню "Анализ". Там вы можете посмотреть весь проект, или просто файл, который вам нужен. Вы могли бы найти еще много проблем, чем вы рассчитывали! Предупреждение в вопросе будет указано в разделе "Вероятные ошибки". Заметьте "вероятный" - ИДЕЯ знает, что это не безошибочно :)

Ответ 4

В моем случае, если я использую MY_ACTUAL_CLASS_NAME.getBoolean(), он не жалуется (поскольку метод является статическим). Может быть, потому, что IntelliJ Idea не учитывает статичность (возможная ошибка здесь)