Как писать условные операторы в Java
Автор выбрал программу Write for DOnations.
Введение
Условные операторы изменяют ход выполнения программы. Условные операторы также называются инструкциями ветвления, потому что при выполнении условия поток переходит в одну сторону в одну ветвь кода. Если условие не выполняется, оценивается другое условие (если оно есть). Эта оценка продолжается до тех пор, пока все условия не будут оценены как true
или false
. Например, вы можете сравнить два числа (x
и y
) со следующими условными операторами: x > y
, x=y
и x < y
. Если x
равно 1
и y
равно 2
, будет произведено три оценки, пока не будет получен окончательный x < y
условное выражение оценивается как true
.
Есть два типа условных выражений. Первый тип — это if
и его расширенные варианты else if
. Этот тип широко используется. Второй тип — switch
, более конкретный и ограниченный.
В этом руководстве вы напишете условные операторы на Java и узнаете о вариантах использования, преимуществах и недостатках каждого типа.
Предпосылки
Чтобы следовать этому руководству, вам понадобятся:
- Среда, в которой вы можете выполнять программы Java, чтобы следовать примерам. Чтобы настроить это на вашем локальном компьютере, вам потребуется следующее:
- На вашем компьютере установлена Java (версия 11 или выше) с компилятором, входящим в комплект Java Development Kit (JDK). Для Ubuntu и Debian следуйте инструкциям по загрузке для установки Java.
- Для компиляции и запуска примеров кода в этом руководстве используется руководство Introduction to JShell.
Знакомство с Java и объектно-ориентированным программированием, которое вы можете найти в нашем руководстве «Как написать свою первую программу на Java».
Понимание типов данных Java, которое обсуждается в нашем руководстве «Понимание типов данных в Java».
Различие между утверждениями и блоками
Когда выполняется условный оператор и поток выполнения направляется на соответствующую ветвь кода, эта ветвь может быть либо отдельной инструкцией, либо блоком кода. Операторы и блоки кода обрабатываются по-разному, поэтому важно различать их.
оператор – это отдельная единица выполнения, обычно состоящая из одной строки и заканчивающаяся точкой с запятой. Например, используйте следующий оператор для печати
example
:- System.out.println("example");
Информация: Чтобы следовать примеру кода в этом руководстве, откройте инструмент Java Shell в вашей локальной системе, выполнив команду
jshell
. Затем вы можете копировать, вставлять или редактировать примеры, добавляя их после приглашенияjshell>
и нажимаяENTER
. Чтобы выйти изjshell
, введите/exit
.Этот оператор использует метод
println()
для печати строки, которая в данном случае являетсяexample
. Если не указано иное, Java выполнит этот оператор безоговорочно.Примечание:
Более того, в некоторых случаях, например, с лямбда-выражениями, более удобно и интуитивно понятно распределить операторы по нескольким строкам. В любом случае, Java не предъявляет синтаксических требований к новым строкам в операторе, и вы можете просто продолжить оператор на новой строке. В качестве упражнения попробуйте переписать некоторые примеры из этого руководства и разделить операторы на несколько строк.
Когда вы группируете операторы, чтобы они выполнялись вместе, вы используете блок. блок — это группа из нуля или более операторов, начинающаяся с открывающей скобки (
{
) и заканчивающаяся закрывающей (}
). Вы можете переписать предыдущий код и поместить его в такой блок:- {
- System.out.println("example");
- }
В приведенном выше блоке вы использовали четыре пробела перед
System.out.println(example);
. Эти четыре пробела называются отступами. В отличие от других языков программирования, таких как Python, отступы в Java не требуются и не влияют на код. Однако для лучшей читаемости и по соглашению строки внутри блока начинаются с отступа в четыре пробела. Большинство редакторов кода поддерживают автоматические отступы, но соглашения в разных языках программирования и даже в разных редакторах различаются. Таким образом, если ваш редактор кода поддерживает отступы, убедитесь, что для него установлено четыре пробела при написании кода Java.Jshell
, который рекомендуется и используется в этом руководстве, автоматически устанавливает четыре пробела в качестве отступа.В этом случае размещение кода внутри блока не имеет значения, поскольку условий нет. Таким образом,
example
будет напечатан независимо от того, находится ли оператор внутри блока. Когда вы запустите два предыдущих примера вjshell
, вы получите один и тот же вывод в обоих случаях:OutputexampleПриведенный выше вывод показывает, что инструкция для печати
example
работает так же, как внутри блока, так и вне его.В этом разделе вы узнали об операторах, блоках и о том, как их создавать. В следующем разделе вы добавите условный оператор в блок кода. Таким образом, операторы внутри блока будут выполняться вместе и условно.
Использование одного условного оператора If
Наиболее часто используемым условным оператором является оператор
if
. Он универсален и подходит для всех нужд условного сравнения, если результатом сравнения является логическое значение (true
илиfalse
). Условиеif
может быть простым условием или иметь более сложную структуру, которую вы будете использовать в следующих разделах.Одиночный оператор
if
используется для выполнения фрагмента кода при одном условии. Вы поместите условно исполняемый код внутрь блока и поместитеif (логическое выражение)
в начале. Если выражение и, следовательно, условие имеют значениеtrue
, только тогда будет выполнен блок кода. Если выражение оценивается какfalse
, код условного блока будет пропущен.В этом примере вы напишете фрагмент кода, который сравнивает два числа. В зависимости от результата сравнения может быть напечатано сообщение. Добавьте следующие строки в
jshell
:- int x = 1;
- int y = 0;
- if (x > y) {
- System.out.println(x + " is bigger than " + y);
- }
В первых двух строках вы определяете две переменные:
x
иy
. Третья строка представляет собой условныйif (x > y)
, который сравнивает, больше лиx
, чемy
. Сравнение всегда в скобках.Код блока начинается с первой открывающей скобки (
{
) и заканчивается закрывающей скобкой (}
). Внутри блока оператор использует методprintln()
для вывода того, чтоx больше, чем y
. Код блока будет выполняться, только если это условиеtrue
.Когда вы запустите этот код в
jshell
, вы получите следующий вывод:Outputx ==> 1 y ==> 0 1 is bigger than 0Первые две строки вывода подтверждают значения
x
иy
. Строка 3 читает1 больше, чем 0
, что означает, что условный операторtrue
:x
больше, чемy
. Если вы изменитеx
на меньшее, чемy
, сообщение не будет напечатано.Самое важное правило в условных операторах заключается в том, что вычисляемое выражение должно иметь значение
boolean
. В любом другом случае вы получите сообщение об ошибке, что то, что вы сравниваете, не может быть преобразовано вboolean
.Для дополнительной практики попробуйте вызвать ошибку небулевым выражением. Для этого поместите переменную
int
, которую нельзя преобразовать вboolean
, в условные скобки следующим образом:- int x = 1;
- if (x) {
- System.out.println("Will this work?");
- }
В строке 1 вы определяете переменную
int
x
и присваиваете ей значение (1
). Строка 2 — это условиеif (x)
, которое приведет к сбою программы, посколькуx
не может быть преобразовано в логическое значение. Когда вы запустите приведенный выше код вjshell
, вы получите следующую ошибку:Outputx ==> 1 | Error: | incompatible types: int cannot be converted to boolean | if (x) { | ^Первая строка подтверждает, что
x
получил значение1
. В следующих строках описывается ошибка, связанная снесовместимыми типами
, и поясняется, что значениеint
, такое какx
, не может быть преобразовано влогическое значение
значение. Всякий раз, когда вы получаете такую ошибку, вы будете знать, что нужно перепроверить свое сравнение.Небулев условный оператор, подобный этому, вероятно, является наиболее распространенной ошибкой при использовании условных выражений. К счастью, современные IDE (Integration Development Environments) ловят такие ошибки, как вы пишете. Тем не менее, даже если вы не используете IDE, ошибки очевидны.
Написание условных операторов if без блока
Одной из особенностей условных выражений
if
в Java является то, что существует более короткий способ их написания без использования блока кода. Хотя использование условных выражений без блока кода не рекомендуется, вы должны знать, что такой код можно написать. С практической стороны, если вы готовитесь к экзамену по Java или идете на собеседование, вы можете столкнуться с такими запутанными примерами и должны быть к этому готовы.Например, вместо использования блока кода вы можете написать такое выражение:
- int x = 1;
- int y = 0;
- if (x > y)
- System.out.println(x + " is bigger than " + y);
Отличие от предыдущего примера в том, что после условного оператора
if (x > y)
нет блока кода. Вместо этого целевой операторSystem.out.println(x + больше, чем + y)
следует сразу после условного оператораif (x > y)
.Когда вы запустите это в
jshell
, вы получите тот же результат, что и в предыдущем примере:Outputx ==> 1 y ==> 0 1 is bigger than 0Значения
x
иy
будут напечатаны в первых двух строках. Подтверждающее сообщение о том, что1 больше 0
, печатается в строке 3.Когда после условного оператора нет блочного кода, от него зависит только строка сразу после условного оператора. В этом случае любые операторы после строки 4 будут выполняться независимо от условного оператора. Например, попробуйте изменить
x
на0
, чтобы оно не превышалоy
, и добавьте пятую строку следующим образом:- int x = 0;
- int y = 0;
- if (x > y)
- System.out.println(x + " is bigger than " + y);
- System.out.println("This line is always printed.");
Когда вы запустите приведенный выше код в
jshell
, вы получите следующий вывод:Outputx ==> 0 y ==> 0 This line is always printed.Значения
x
иy
печатаются в строках 1 и 2. Оба значения равны0
, что означает, что они равны. Из-за этого условный операторx > y
возвращает false. Таким образом, четвертая строка, в которой говорится, чтоx больше, чем y
, не печатается. Однако печатается строка 5, поскольку ее выполнение не зависит от условного оператора.Кроме того, отступ в строке 5 не нужен. Он был включен, чтобы предположить, что выполнение строки 5 зависит от условного оператора, что не так. Этот отступ можно было бы опустить, но это не сделало бы код понятнее.
Использование условных выражений без блока кода не является интуитивно понятным или простым для понимания, поэтому вы должны экономно использовать сокращенный синтаксис. Чтобы ваш код оставался чистым и понятным, лучше использовать блочные операторы, потому что они более читабельны и позволяют вам иметь более одной строки условно исполняемого кода.
Вложенные операторы
if
— еще один пример кода, который можно написать, но обычно не рекомендуется. В следующем разделе вы изучите вложенные операторыif
, чтобы лучше понять их ценность и недостатки.Вложенные операторы if
Чтобы создать более сложную условную структуру, можно объединить несколько операторов
if
. Чтобы создать вложенные операторыif
, вы помещаете другой операторif
внутрь родительского оператораif
, а не в блок кода.Эта практика обычно не рекомендуется, поскольку она затрудняет чтение и понимание кода. Однако вложенные операторы if иногда имеют практическое применение, поэтому полезно с ними ознакомиться.
Чтобы понять, как это делается, вы расширите предыдущий пример, добавив еще один оператор
if
. Вы снова сравнитеy
, чтобы оценить, равен ли он0
. Добавьте следующие строки вjshell
:- int x = 1;
- int y = 0;
- if (x > y) {
- if (y == 0) {
- System.out.println("This is legal but does not look clean.");
- }
- }
Первые три строки не изменились по сравнению с предыдущими примерами: вы определяете две переменные
int
(x
иy
) и сравниваете их. В строке 4 другой операторif
сравнивает, равен лиy
0
. Еслиtrue
, Java перейдет к строке 5, в которой есть операторprintln()
с сообщениемЭто допустимо, но не выглядит чистым.
.Когда вы запустите это в
jshell
, вы получите следующий вывод:Outputx ==> 1 y ==> 0 This is legal but does not look clean.Первые две строки подтверждают значения
x
иy
. Строка 3 гласит:Это допустимо, но не выглядит чистым
. Это сообщение подтверждает, что код блока был выполнен, поскольку оба условияif
выполнены:x > y
иy == 0
.Вы можете бесконечно вкладывать такие операторы
if
. Однако с каждым вложенным операторомif
вы увеличиваете сложность кода и снижаете его читабельность. Вот почему вложение операторовif
обычно не считается хорошей практикой кодирования.Однако вложенные условные структуры имеют некоторое практическое применение. Иногда может показаться целесообразным пожертвовать удобочитаемостью и увеличить сложность в пользу написания более короткого кода и потенциальной экономии времени. В результате вы можете столкнуться с вложенными операторами во время экзаменов, собеседований или в реальном продуктивном коде.
Использование расширенных операторов If с операторами Else If и Else
Условные выражения
if
могут быть дополнительно расширены для обработки дополнительных критериев соответствия с помощью дополнительных операторовelse if
иelse
. Операторыelse
можно использовать только после начального оператораif
. С помощьюelse if
вы можете добавлять неограниченное количество дополнительных условных операторов, аналогично первомуif
. С помощью последнего необязательногоelse
вы указываете путь по умолчанию, по которому должен следовать поток программы в случае, если предыдущий условный оператор не совпал.С помощью
else if
иelse
вы можете разветвить поток своей программы в большем количестве направлений, чем с однимif
. Таким образом, вы можете строить сложные условные конструкции, которые невозможно построить никаким другим способом. Разветвление кода в различных направлениях позволяет обрабатывать более сложные бизнес-кейсы. Тем не менее, бизнес-требования в производстве многочисленны, и процесс проектирования не обязательно прямолинеен.Начните со следующего примера кода, чтобы получить представление об операторах
else if
иelse
. Вы расширите ранее использованный код и добавите больше условных ветвей. Эти новые условия продолжат сравниватьx
иy
:- int x = 1;
- int y = 0;
- if (x > y) {
- System.out.println(x + " is bigger than " + y);
- } else if (x < y) {
- System.out.println(y + " is bigger than " + x);
- } else if (x == y) {
- System.out.println(x + " is equal to " + y);
- } else {
- System.out.println(x + " cannot be compared to " + y);
- }
Согласно приведенному выше коду, строки 1 и 2 определяют две переменные (
x
иy
) со значениями1
и0
. В строках 3 и 4 вы оцениваете, больше лиx
, чемy
, с помощью оператораif
. Если оценкаtrue
, текстx больше, чем y
будет напечатан и условная структура будет закрыта. Если оценкаfalse
, программа перейдет к следующему условному выражению. Пока что код такой же, как и в предыдущих примерах.В строке 5 после закрывающей скобки оператора
if
следует операторelse if
. Он имеет синтаксис, аналогичныйif
: в круглых скобках есть логическое выражение и следующий за ним блок кода. Выражение оценивает, больше лиy
, чемx
, что противоположно предыдущему операторуif
. Если выражение равноtrue
, будет выполнен блок кода, следующий за ним, и снова произойдет выход из условной структуры. В данном случае это оператор в строке 6, который напечатаетy больше, чем x
.В строке 7 есть еще один случай
else if
. На этот раз вы проверяете, равен лиx
y
в скобках. Еслиtrue
, оператор в строке 8 будет выполнен и напечатаетx равно y
. Такие операторыelse if
можно добавлять бесконечно, один за другим и оценивая разные условия.В строке 9 находится последний оператор
else
. Он всегда является окончательным и не имеет условия, что означает, что его ветвь всегда вводится, если никакое другое условное выражение не соответствует. Другими словами, блок кода послеelse
выполняется, если ранее не выполнялось условиеif
илиelse if
. Если бы это былоtrue
, код в строке 10 был бы выполнен, выводя, чтоx нельзя сравнивать с y
.В таких сложных условных структурах требуется только первый оператор
if
. Если вы хотите сделать дополнительные сравнения, у вас может быть ноль или более операторовelse if
. В конце концов, вы можете поместить один необязательныйelse
для соответствия, если никакие другие условные выражения не совпали.Когда вы запустите приведенный выше код в
jshell
, вы получите следующий вывод:Outputx ==> 1 y ==> 0 1 is bigger than 0Первая и вторая строки приведенного выше вывода подтверждают значения
x
иy
:1
и0
. В третьей строке выводится1 больше 0
, что подтверждает, что логическое выражение(x > y)
вернуло значение true и код блока после его выполнения.Написание операторов
if
,else if
иelse
— это хороший способ написания сложных условных структур, поскольку вы можете поместить разные условия в каждый. оператор if
иelse if
. В приведенном выше примере вы сначала сравнилиx > y
, затем противоположноеx < y
и, наконец,x == y
. Код остается читаемым и управляемым даже в случаях с несколькими сравнениями.Однако, если вам нужно сделать больше сравнений, добавление дополнительных операторов
else if
сделает код трудным для понимания и даже запутанным. Вот почему вы должны делать свои структуры маленькими и простыми, когда это возможно. Кроме того, в некоторых случаях существует альтернатива таким сложным структурам с использованием оператораswitch
, который вы будете использовать в следующем разделе.Использование условий переключения
Оператор
switch
— это еще один условный оператор, который можно использовать для построения структур принятия решений. Он похож на операторif
, поскольку его можно использовать для условного управления ходом программы. Однако операторswitch
работает с одной переменной и сопоставляет ее с различными предопределенными случаями. Таким образом, вы не можете вычислять логические выражения, такие какx > y
. Вместо этого вы можете иметь, например, переменнуюint
и сопоставлять ее значение с другими переменнымиint
; когда есть совпадение (то естьcase
), поток программы будет перенаправлен в соответствии с совпадением.Условные операторы
switch
имеют два важных правила. Во-первых, сравниваемая переменная может иметь только определенные типы данных, такие как примитивные типыint
иchar
, а также ссылочные типыString
иЦелое число
. (Полный список поддерживаемых типов данных можно найти в официальной документацииswitch
.) Таким образом, вы не можете использовать переменныеboolean
, поэтомуswitch
Условные выражения не могут заменять условные выраженияif
.Другое важное правило заключается в том, что значения для операторов
case
должны быть константами, похожими на переменные, но перед ними стоит ключевое словоfinal
, когда они определены. В отличие от переменных, вы не можете изменить значение константы после ее определения. Константы будут подробно рассмотрены в будущих руководствах из нашей серии Java.Структура
switch
более ограничена, чем структураif
, и не является ее полной заменой. Тем не менее, у него есть уникальное преимущество: он более удобочитаем и лучше подходит для большего количества сравнений, когда это возможно.Например, представьте, что вы хотите сопоставить числовое представление каждого месяца (от 1 до 12) с названием месяца. Со структурой
if
-else if
вам придется сделать двенадцать похожих сравнений. Но с помощьюswitch
вы можете сделать это более аккуратно, не повторяя код.Чтобы попрактиковаться в использовании синтаксиса условия
switch
в этом примере о месяцах, добавьте следующие строки вjshell
. Существует переменнаяint
, численно представляющая месяц года, иcase
для названия каждого месяца:- int monthOfYear = 1;
- switch (monthOfYear) {
- case 1:
- System.out.println("January");
- break;
- case 2:
- System.out.println("February");
- break;
- default:
- System.out.println("Not a month");
- }
В строке 1 есть переменная
monthOfYear
со значением1
. Эта переменная будет использоваться для оператораswitch
. В строке 2 находится определение оператораswitch
. ПеременнаяmonthOfYear
помещена в круглые скобки, чтобы показать, что она будет сравниваться. После этого начинается блок кода, внутри которого описываются различные условияcase
.В строке 3 появляется первый
case
со значением1
. Первое сравнение будет заключаться в том, равен лиmonthOfYear
1
. Двоеточие (:
) всегда следует за сравниваемым значением. В строке 4 находится методprintln()
для вывода, который в случае совпадения1
должен напечататьЯнварь
в качестве названия месяца. Эта строка может содержать ноль или более операторов в ноль или более строк, то есть ее можно пропустить.После первого случая следует оператор
break
в строке 5, который вызывает выход из условной структурыswitch
при выполнении условия. Таким образом, после выполненияbreak
никакие другие условияcase
не будут оцениваться. Вместо этого поток программы продолжится после закрывающей скобки условного выраженияswitch
, которое в этом примере находится в строке 11. Обратите внимание, чтоbreak
является необязательным, и вы можете забыть его включить. В этом случаеswitch
будет продолжать оценивать оставшиеся варианты, а не прерывать условную структуру при наличии совпадения. Это может привести к неожиданному выводу и проблемам, которые трудно отладить.Следующее условие
case
находится в строках 6, 7 и 8, и оно будет соответствовать значениюmonthOfYear
, равному2
. Эти три строки имеют тот же синтаксис, что и предыдущие три, но с новой строкой дляФевраль
в строке 7. Для краткости условные выраженияcase
для оставшихся десяти месяцев был опущен. В противном случае они также следовали бы этой структуре с новыми строками для каждого именованного месяца.В строке 9 находится оператор
default
. У него нет условий, и поэтому оно всегда совпадает. Он является необязательным и используется для определения пути по умолчанию для потока программы, когда ни один из ранее перечисленных вариантов не соответствует. Это похоже на операторelse
в условных выраженияхif
.В строке 11 есть закрывающая скобка для завершения блока кода для условных операторов.
Чтобы выполнить приведенный выше код, вставьте его в
jshell
. Вы получите следующий вывод:OutputmonthOfYear ==> 1 JanuaryПервая строка подтверждает, что значение
monthOfYear
равно1
. Во второй строке выводитсяЯнварь
, что означает соответствие условномуcase
для значения1
:monthOfYear
равно1
, что запускает оператор на следующей строке для печатиJanuary
.В качестве упражнения попробуйте изменить значение
monthOfYear
, добавить дополнительные условияcase
и даже удалить операторыbreak
, чтобы понять, как изменится результат. .Заключение
В этом руководстве вы использовали условные операторы для управления потоком выполнения. Вы узнали, когда уместно использовать операторы
if
иswitch
, и написали с ними несколько примеров кода. Вы также узнали о передовых методах чистого кода и о том, как избежать распространенных ошибок, связанных с условными выражениями.Чтобы узнать больше о Java, ознакомьтесь с нашей серией статей How To Code in Java.