Java: Логические выражения
Одиночное сравнение вроде age >= 18 отвечает на один вопрос. Реальные проверки собирают несколько таких вопросов в одно составное выражение. Форма на сайте принимает данные и проверяет сразу совершеннолетие пользователя и его согласие на обработку данных. Все это умещается в одну строку:
var age = 20;
var hasConsent = true;
System.out.println(age >= 18 && hasConsent); // => trueСоставное логическое выражение в Java всегда вычисляется в true или false. Промежуточные части тоже превращаются в логические значения, и финальный результат собирается из них шаг за шагом.
Порядок вычисления
В одном выражении встречаются арифметика, сравнения и логические операторы. Java вычисляет их в строгом порядке приоритетов:
Приоритет (от высокого к низкому):
() скобки
↓
* / % + - арифметика
↓
< <= > >= == != сравнения
↓
! отрицание
↓
&& логическое И
↓
|| логическое ИЛИСначала считается арифметика, затем сравнения дают true или false, и только потом логические операторы соединяют эти значения. Оператор && истинен, когда истинны оба операнда. Оператор || истинен, когда истинен хотя бы один. Оператор ! меняет значение на противоположное.
Вычисление по шагам
Разберем выражение из примера выше. У нас age равен 20, а hasConsent равен true:
age >= 18 && hasConsent
20 >= 18 && true // подставили значения переменных
true && true // сравнение 20 >= 18 дало true
true // оба операнда && истинныВозьмем выражение посложнее, где участвуют все три оператора. Проверяем, что число в диапазоне от 1 до 10 и при этом четное:
var number = 4;
System.out.println(number >= 1 && number <= 10 && number % 2 == 0); // => trueJava разворачивает его так:
4 >= 1 && 4 <= 10 && 4 % 2 == 0
true && true && 4 % 2 == 0 // два сравнения дали true
true && true && 0 == 0 // посчитали остаток 4 % 2
true && true && true // последнее сравнение дало true
true // все операнды && истинныСкобки и приоритет
Когда в выражении смешаны && и ||, порядок задают скобки. Без них && срабатывает раньше ||, и смысл может оказаться не таким, как задумано:
// && связывает b и c, поэтому это a || (b && c)
System.out.println(true || false && false); // => true
// скобки меняют порядок, сначала считается то, что внутри
System.out.println((true || false) && false); // => falseПервое выражение сначала вычисляет false && false, получает false, а затем true || false дает true. Во втором случае скобки заставляют посчитать true || false первым, получается true && false, и результат false.
Сокращенное вычисление
Java останавливается, как только результат уже понятен. Если левый операнд || истинен, правый не вычисляется, ведь все выражение уже истинно. Если левый операнд && ложен, правый тоже пропускается:
var hasAccess = true;
System.out.println(hasAccess || age < 0); // => true, правую часть Java не считаетТакое поведение называют сокращенным вычислением. Оно ускоряет проверки и защищает от лишней работы в правой части выражения.
Задание
Форма регистрации принимает данные пользователя. Перед отправкой программа проверяет сразу два условия: пользователю есть 18 лет и он отметил согласие на обработку данных.
В переменной age лежит возраст 20, а в переменной hasConsent лежит значение true. Соедините проверку совершеннолетия age >= 18 и согласие hasConsent оператором && и выведите результат составного выражения на экран.
Ожидаемый вывод:
trueПолезное
Java: Логические выражения
Одиночное сравнение вроде age >= 18 отвечает на один вопрос. Реальные проверки собирают несколько таких вопросов в одно составное выражение. Форма на сайте принимает данные и проверяет сразу совершеннолетие пользователя и его согласие на обработку данных. Все это умещается в одну строку:
var age = 20;
var hasConsent = true;
System.out.println(age >= 18 && hasConsent); // => trueСоставное логическое выражение в Java всегда вычисляется в true или false. Промежуточные части тоже превращаются в логические значения, и финальный результат собирается из них шаг за шагом.
Порядок вычисления
В одном выражении встречаются арифметика, сравнения и логические операторы. Java вычисляет их в строгом порядке приоритетов:
Приоритет (от высокого к низкому):
() скобки
↓
* / % + - арифметика
↓
< <= > >= == != сравнения
↓
! отрицание
↓
&& логическое И
↓
|| логическое ИЛИСначала считается арифметика, затем сравнения дают true или false, и только потом логические операторы соединяют эти значения. Оператор && истинен, когда истинны оба операнда. Оператор || истинен, когда истинен хотя бы один. Оператор ! меняет значение на противоположное.
Вычисление по шагам
Разберем выражение из примера выше. У нас age равен 20, а hasConsent равен true:
age >= 18 && hasConsent
20 >= 18 && true // подставили значения переменных
true && true // сравнение 20 >= 18 дало true
true // оба операнда && истинныВозьмем выражение посложнее, где участвуют все три оператора. Проверяем, что число в диапазоне от 1 до 10 и при этом четное:
var number = 4;
System.out.println(number >= 1 && number <= 10 && number % 2 == 0); // => trueJava разворачивает его так:
4 >= 1 && 4 <= 10 && 4 % 2 == 0
true && true && 4 % 2 == 0 // два сравнения дали true
true && true && 0 == 0 // посчитали остаток 4 % 2
true && true && true // последнее сравнение дало true
true // все операнды && истинныСкобки и приоритет
Когда в выражении смешаны && и ||, порядок задают скобки. Без них && срабатывает раньше ||, и смысл может оказаться не таким, как задумано:
// && связывает b и c, поэтому это a || (b && c)
System.out.println(true || false && false); // => true
// скобки меняют порядок, сначала считается то, что внутри
System.out.println((true || false) && false); // => falseПервое выражение сначала вычисляет false && false, получает false, а затем true || false дает true. Во втором случае скобки заставляют посчитать true || false первым, получается true && false, и результат false.
Сокращенное вычисление
Java останавливается, как только результат уже понятен. Если левый операнд || истинен, правый не вычисляется, ведь все выражение уже истинно. Если левый операнд && ложен, правый тоже пропускается:
var hasAccess = true;
System.out.println(hasAccess || age < 0); // => true, правую часть Java не считаетТакое поведение называют сокращенным вычислением. Оно ускоряет проверки и защищает от лишней работы в правой части выражения.
Задание
Форма регистрации принимает данные пользователя. Перед отправкой программа проверяет сразу два условия: пользователю есть 18 лет и он отметил согласие на обработку данных.
В переменной age лежит возраст 20, а в переменной hasConsent лежит значение true. Соедините проверку совершеннолетия age >= 18 и согласие hasConsent оператором && и выведите результат составного выражения на экран.
Ожидаемый вывод:
trueПолезное
Ваше упражнение проверяется по этим тестам
import static org.assertj.core.api.Assertions.assertThat;
import java.io.ByteArrayOutputStream;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.PrintStream;
class AppTest {
public static void main(String[] args) {
final var expected = "true";
ByteArrayOutputStream out = new ByteArrayOutputStream();
System.setOut(new PrintStream(out));
App.main(null);
final var actual = out.toString().trim();
System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out)));
System.out.println(actual);
assertThat(actual).isEqualTo(expected);
}
}Решение учителя откроется через:
20:00
