Почему этот оператор if с проверкой присваивания и равенства возвращает false?


105

Как работает оператор if в Java, если в нем есть присваивание и проверка равенства OR-d вместе ??

public static void test() {
    boolean test1 = true; 
    if (test1 = false || test1 == false) {
        System.out.println("TRUE");
    } else {
        System.out.println("FALSE");
    }       
}

Почему эта печать ЛОЖНА?


1
Запускаем и проверяем. Посмотрите, какое логическое значение печатается, если вы присвоили false и true. Тогда прочтите, как работает OR.
Pratik

2
Я хотел бы сказать, что этот код в режиме отладки дает значение ИСТИНА, а в режиме выполнения дает значение ЛОЖЬ ... Почему это так ??? ... (Я поставил
точку

test1=false, test1==falseесть false, false || falseэто false or falseчто есть false.
Джаред Берроуз

Я знаю, что вы не просили совета, но, поскольку ответы ниже указывают на проблему с приоритетом, вот несколько приемов, которые помогли мне избежать проблем (когда я их придерживаюсь): (1) всегда используйте круглые скобки, когда не на 100% определенные приоритеты или для облегчения разборчивости, чтобы помочь другим разработчикам. Не думайте, что другие запомнят правила приоритета для всех операторов (2). Обычно следует избегать присваиваний if, чтобы избежать путаницы, за исключением очень простых условий if. Есть несколько распространенных исключений (особенно при простых проверках ввода-вывода, сети и т. Д.). Всего два цента.
римский

потому чтоtest1 = true
jono

Ответы:


189

Выражение анализируется не так, как вы думаете. Это не

(test1=false) || (test1 == false)

в этом случае результат был бы true, но

test1 = (false || test1 == false)

false || test1 == falseСначала вычисляется значение выражения, и оно так и есть false, потому что test1оно настроено на trueвход в вычисление.

Причина он обрабатывается таким образом, что преимущество из ||ниже , чем у ==оператора, но выше , чем приоритет оператора присваивания =.


2
+1 @RohanFernando, также обратите внимание, что если вы добавите скобки вокруг присваивания следующим образом: ((test1 = false) || test1 == false)общее значение будет true.
Арнон Зилка

1
Напишите пожалуйста причину почему так происходит парсинг ... Это из-за порядка приоритета операторов?
kondu

3
@kondu Это справедливый дополнительный вопрос, я отредактировал, чтобы добавить ссылку на таблицу приоритетов, которая показывает, что ==это вверху ||, но =внизу ||.
dasblinkenlight

Последний абзац вводит в заблуждение в том смысле, что для понимания того, почему выбран второй синтаксический анализ, а не первый, достаточно знать (легко запоминающееся) правило, согласно которому присваивание имеет более низкий приоритет, чем любой оператор без присваивания (здесь ||). Относительный приоритет ||и ==имеет значение только для того, чтобы показать, что синтаксический анализ не такой test1 = ((false || test1) == false), как в , что я не думаю, что кто-либо мог бы разумно ожидать (кстати, относительный приоритет или, в более общем смысле ||, &&имеет более низкий приоритет, чем отношения, также легко помню, так как использовал все время).
Marc van Leeuwen

1
@MarcvanLeeuwen Относительный приоритет ||и ==vs ||и =объясняет, почему это ведет себя не так, как (общий) случай a == b || c == d.
Аарон Дюфур

83

По сути, это вопрос приоритета. Вы предполагаете, что ваш код эквивалентен:

if ((test1 = false) || (test1 == false))

... но это не так. Фактически это эквивалентно:

if (test1 = (false || test1 == false))

... что эквивалентно:

if (test1 = (false || false))

(потому что test1это trueдля начала)

... что эквивалентно:

if (test1 = false)

который присваивает значение falseк test1, с результатом выражения существ false.

См. Полезную таблицу приоритетов операторов в учебнике Java по операторам .


2

пожалуйста, посмотрите на приоритет операторов

Выражение test1 = false || test1 == falseбудет оценено на следующем шаге.

ШАГ: 1- test1 = false || test1 == false // приоритет ==наивысший

ШАГ: 2- test1 = false || false // Оператор ||имеет более высокий приоритет

ШАГ 3- test1 = false

ШАГ: 4- false

Поскольку логическое значение выражения становится ложным, выполняется инструкция else.


-11

(test1 = false || test1 == false)возвращает false, потому что оба они ложны. (test1 = false || test1 == true)это правда, потому что одна из них верна


1
Совершенно неправильно. Почему вы ответили такой неверной информацией через несколько дней после того, как на вопрос были получены два качественных ответа, описывающих происходящее?
l4mpi

5
Два ответа столь низкого качества не заслуживают индивидуальных письменных комментариев. Вы ведь понимаете, что ваш ответ - чепуха? Если нет, внимательно прочтите два ответа Джона и мигните.
l4mpi
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.