Kamusta! Ngayon ay pag-uusapan natin ang tungkol sa mga operator ng pagtalon sa Java:
return
break
continue
goto
if
) at mga loop ( for
, while
atbp.). Bilang karagdagan sa mga control construct, ang linear execution ng isang program ay maaaring mabago sa pamamagitan ng jump statement. Responsable sila sa pag-redirect ng pagpapatupad ng programa sa isang partikular na lokasyon, na nakadepende sa konteksto at sa partikular na pahayag. Tingnan natin ang bawat isa sa apat na operator.
bumalik
Ito ang operator na kadalasang nagiging pamilyar sa mga bagong dating. Tinatapos ng pahayagreturn
ang pamamaraan kung saan ito tinawag, at ang pagpapatupad ng programa ay babalik sa lokasyon kung saan tinawag ang pamamaraan. Ito return
ay may dalawang anyo:
- Agad na tinapos ang pagpapatupad ng pamamaraan.
- Agad na tinapos ang pagpapatupad ng pamamaraan at nagbabalik ng ilang halaga bilang resulta ng pamamaraan.
return;
return value; // где value — некоторое возвращаемое meaning
Ang mga pamamaraan na nagbabalik ng isang halaga ay dapat na mayroong kahit isang operator return
na may isang return value na garantisadong matatawag, at hindi dapat mayroong operator return
na walang return value. Tingnan natin ang mga halimbawa sa ibaba:
public int sum(int a, int b) {
return a + b;
}
public String getGreetings(String name) {
return "Hello " + name;
}
public int max(int x, int y) {
if (x > y) {
return x;
} else {
return y;
}
}
Sa mga pamamaraan na hindi nagbabalik ng isang halaga (mga pamamaraan void
), ito ay katanggap-tanggap, ngunit hindi kinakailangan, na magkaroon ng hindi bababa sa isang pahayag return
na walang return value, at hindi isang solong pahayag return
na may return value. Tingnan natin ito sa mga halimbawa sa ibaba:
public void print(String s) {
// наличие return в void методах не обязательно
System.out.println(s);
}
//Метод выведет в консоль число, если оно нечетное
public void printIfOdd(int number) {
if (number % 2 == 0) {
// Если число четное, метод завершит свою работу
// Наличие return в void методах опционально
return;
}
System.out.println(number);
}
// Метод выведет в консоль наибольшее meaning из массива
private void printMaxInArray(int[] array) {
if (array == null || array.length == 0) {
/*
Если массив пуст, метод завершит свою работу.
Иногда полезно проверять подобным образом аргументы метода вначале и прерывать выполнение метода, если аргументы не подходят для дальнейшей корректной работы
*/
System.out.println("Empty array");
return;
}
int max = array[1];
for (int i = 1; i < array.length; i++) {
if (array[i] > max) {
max = array[i];
}
}
System.out.println(max);
}
mga label
Bago tingnan angbreak
at operator continue
, gusto kong pag-usapan ang tungkol sa mga label sa Java. Mahalaga ito dahil sa ilang sitwasyon, break
at continue
ginagamit ang mga operator kasabay ng mga label. Ngunit una, subukang sagutin ang tanong kung ang code na ito ay mag-compile:
public static void main(String[] args) {
https://www.google.com/
System.out.println("Interesting...");
}
Ang label ay isang pinangalanang piraso ng code. Ang label mismo ay hindi nagbibigay ng anumang pag-andar. Ito ay tulad ng isang bookmark sa code na nilalayon ng programmer na gamitin sa ibang pagkakataon. Ang isang label sa code ay tinukoy nang simple - sa pamamagitan ng isang pangalan at isang tutuldok. Halimbawa:
labelName:
outerLoop:
printing:
anyWordYouLike:
public static void main(String[] args) {
definePrintName:
System.out.println("Таблица Умножения");
loop1:
for (int i = 1; i <= 10; i++) {
loop2:
for (int j = 1; j <= 10; j++) {
System.out.printf("%4d", i * j);
}
System.out.println();
}
}
Ang output ng pamamaraan main
ay ang mga sumusunod:
Таблица Умножения
1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 12 14 16 18 20
3 6 9 12 15 18 21 24 27 30
4 8 12 16 20 24 28 32 36 40
5 10 15 20 25 30 35 40 45 50
6 12 18 24 30 36 42 48 54 60
7 14 21 28 35 42 49 56 63 70
8 16 24 32 40 48 56 64 72 80
9 18 27 36 45 54 63 72 81 90
10 20 30 40 50 60 70 80 90 100
Process finished with exit code 0
Sa halimbawa sa itaas definePrintName
, loop1:
at loop2:
mga label. loop1:
at loop2:
"markahan" ang dalawang cycle - panlabas at panloob. Titingnan natin ang paggamit ng mga label sa seksyon sa ibaba. Pansamantala, kung sumagot ka ng "hindi" sa tanong kung mag-compile ang code na ito:
public static void main(String[] args) {
https://www.google.com/
System.out.println("Interesting...");
}
Subukang sagutin itong muli, gamit ang IDE.
pahinga
Ang operatorbreak
ay ginagamit sa dalawang kaso:
- Upang kumpletuhin ang anumang sangay ng pagpapatupad sa isang bloke ng switch-case.
- Upang matakpan ang pagpapatupad ng isang loop.
break labelName; // Синтаксис оператора с меткой
break; // Синтаксис оператора без метки
В блоках switch-case оператор break
используется без меток:
public static void main(String[] args) {
int dayOfWeekInt = 4;
String dayOfWeek;
switch (dayOfWeekInt) {
case 1:
dayOfWeek = "Monday";
break;
case 2:
dayOfWeek = "Tuesday";
break;
case 3:
dayOfWeek = "Wednesday";
break;
case 4:
dayOfWeek = "Thursday";
break;
case 5:
dayOfWeek = "Friday";
break;
case 6:
dayOfWeek = "Saturday";
break;
case 7:
dayOfWeek = "Sunday";
break;
default:
dayOfWeek = "Неизвестный день";
break;
}
System.out.println("Сегодня " + dayOfWeek);
}
В циклах оператор break
используют для прерывания дальнейших итераций после того, How достигнуты определенные условия. Часто такое можно встретить, когда необходимо перебрать массив or коллекцию элементов и найти в ней Howой-то элемент, удовлетворяющий нужным условиям. Рассмотрим такой пример. У нас есть массив и нам необходимо определить, содержит ли массив отрицательные элементы:
int a[] = {1,2,234,-123,12,-2,312,0,412,433};
boolean arrayHasNegativeElements = false;
for (int i = 0; i < a.length; i++) {
if (a[i] < 0) {
/*
Как только найдется
хотя бы один отрицательный элемент,
мы прервем цикл с помощью
оператора break, потому что
мы выяснor то, что нас интересовало,
и дальнейший перебор элементов не имеет смысла.
*/
arrayHasNegativeElements = true;
break;
}
}
Рассмотрим тот же пример с различными циклами. Цикл for-each
:
public static void main(String[] args) {
int a[] = {1,2,234,-123,12,-2,312,0,412,433};
boolean arrayHasNegativeElements = false;
for (int number : a) {
if (number < 0) {
arrayHasNegativeElements = true;
break;
}
}
}
Цикл while
:
public static void main(String[] args) {
int a[] = {1,2,234,-123,12,-2,312,0,412,433};
boolean arrayHasNegativeElements = false;
int counter = 0;
while (counter < a.length) {
if (a[counter] < 0) {
arrayHasNegativeElements = true;
break;
}
counter ++;
}
}
Цикл do-while
:
public static void main(String[] args) {
int a[] = {1,2,234,-123,12,-2,312,0,412,433};
boolean arrayHasNegativeElements = false;
int counter = 0;
do {
if (a[counter] < 0) {
arrayHasNegativeElements = true;
break;
}
counter ++;
} while (counter < a.length);
}
Еще одним примером оператора break
в циклах является прерывание бесконечного цикла при достижении определенных условий. Приведем пример программы, выводящей строку, которую ввел пользователь до тех пор, пока юзер не введёт слово “stop”:
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String line;
while (true) {
line = scanner.nextLine();
if ("stop".equals(line)){
/*
Прерываем бесконечный цикл,
при достижении
определенного условия
*/
break;
}
System.out.println("Пользователь ввел: " + line);
}
}
Рассмотрим использование оператора break
совместно с меткой. Прерывание с меткой используется в случаях с несколькими циклами, причем вложенными один в другой. В таком случае один из циклов (or же все циклы) помечается меткой. Далее оператор break
совместно с указанием метки прерывает нужный цикл. Рассмотрим пример, в котором нам необходимо понять, есть ли отрицательный элемент, но только не в массиве, а в матрице:
public static void main(String[] args) {
int[][] a = {
{1, 2, 3},
{-412, 12, 0},
{1223, 474, -54}
};
boolean hasNegative = false;
searchNegative:
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[i].length; j++) {
if (a[i][j] < 0) {
/*
Если использовать break без метки,
тогда прервется вложенный цикл for,
но внешний продолжит выполнять свои итерации
и поиск продолжится.
Поэтому мы "помечаем" внешний цикл меткой `searchNegative`
и прерываем внешний цикл оператором break совместно с нужной меткой.
*/
hasNegative = true;
break searchNegative;
}
}
}
}
сontinue
У оператораcontinue
также есть две формы — с меткой и без:
continue; // форма оператора без метки
continue labelName; // форма оператора с меткой
В отличии от оператора break
, который прерывает все оставшиеся итерации цикла, оператор continue
прерывает текущую итерацию и приводит к запуску следующей.Такое может быть полезно, если нужно провести некоторые операции над elementми, которые удовлетворяют определенным условиям. Скажем, у нас есть строка, и мы хотим посчитать количество слов, начинающихся с буквы “м”:
public static void main(String[] args) {
String sentence = "Мама мыла раму";
String[] words = sentence.split(" ");
int mWordsCount = 0;
for (int i = 0; i < words.length; i++) {
if ( ! words[i].toLowerCase().startsWith("м")) {
/*
Если слово не начинается с буквы м,
то текущая итерация прервется и цикл
ПРОДОЛЖИТ выполнение со следующей итерации
*/
continue;
}
mWordsCount ++;
}
System.out.println("Кол-во слов, начинающихся с буквы М в предложении: " + "[" + sentence + "] = " + mWordsCount);
}
После выполнения данного codeа будет такой вывод в консоли:
Кол-во слов, начинающихся с буквы М в предложении: [Мама мыла раму] = 2
Оператор continue
совместно с меткой также используется при переборе элементов. Представим себе матрицу, в которой нам нужно посчитать количество строк с отрицательными elementми:
public static void main(String[] args) {
int[][] a = {
{1, 23, -1, 23, -12},
{21, 21, 0, 23, 123, 45},
{123, 3},
{123, -5, 4, -3},
{-1, -2, -3}
};
int rowsWithNegativeElementsCount = 0;
rowsLoop:
// Проходим по каждой строке
for (int[] arr : a) {
for (int number : arr) {
if (number < 0) {
/*
Если в текущей строке найдется
хотя бы 1 отрицательный элемент,
тогда мы увеличим переменную счетчик,
и с помощью оператора continue rowsLoop
прервем текущую итерацию внешнего цикла и
принудительно начнем следующую
*/
rowsWithNegativeElementsCount ++;
continue rowsLoop;
}
}
}
System.out.println("Rows With Negative Elements Count = " + rowsWithNegativeElementsCount);
}
Выводом данного codeа будет:
Rows With Negative Elements Count = 3
Стоит сказать, что операторы break
, continue
и return
можно по-разному использовать для достижения одной и той же функциональности. Так, можно переписать последний пример и instead of continue
использовать break
:
public static void main(String[] args) {
int[][] a = {
{1, 23, -1, 23, -12},
{21, 21, 0, 23, 123, 45},
{123, 3},
{123, -5, 4, -3},
{-1, -2, -3}
};
int rowsWithNegativeElementsCount = 0;
for (int[] arr : a) {
for (int number : arr) {
if (number < 0) {
rowsWithNegativeElementsCount ++;
break;
}
}
}
System.out.println("Rows With Negative Elements Count = " + rowsWithNegativeElementsCount);
}
Difference между break
и continue
с меткой заключается в том, что break
завершает итерации цикла, в котором он написан. А continue
с меткой пропускает текущую итерацию цикла отмеченного меткой. В некоторых ситуациях можно заменять одно на другое, и в функциональности программы все останется прежним. О том, что лучше выбрать (спойлер: читаемость codeа), расскажем немного ниже. Оператор break
можно заменить не только на continue
с меткой, но и на return
. Только перед этим нужно вынести вложенный цикл в отдельный метод:
public static void main(String[] args) {
int[][] a = {
{1, 23, -1, 23, -12},
{21, 21, 0, 23, 123, 45},
{123, 3},
{123, -5, 4, -3},
{-1, -2, -3}
};
int rowsWithNegativeElementsCount = 0;
for (int[] arr : a) {
if (arrayHasNegativeElements(arr)) {
rowsWithNegativeElementsCount ++;
}
}
System.out.println("Rows With Negative Elements Count = " + rowsWithNegativeElementsCount);
}
static boolean arrayHasNegativeElements(int[] array) {
for (int number : array) {
if (number < 0) {
return true;
}
}
return false;
}
Уйма способов написать одно и то же. Какой же выбрать? В промышленном программировании в этом вопросе решает легкость восприятия codeа. Чем проще написано, тем лучше. Чем больше вложенных циклов, тем сложнее воспринимать code. Особенно если циклы отмечены различными метками, которые используются в прерываниях и продолжениях (break
и continue
). Если есть возможность не использовать метки, лучше так и делать. В ином случае старайтесь писать максимально понятно и красиво.
goto
В некоторых языках программирования существует операторgoto
. Обычно он перенаправляет выполнение codeа в Howую-либо часть программы, помеченную меткой. Но в Java goto
, можно сказать, и есть, и нет. Давайте разбираться. Список ключевых слов в Java включает слово goto
. Однако данный оператор помечен How not used (не используется). Дело в том, что Джеймс Гослинг, создатель ЯП Java изначально заложил в JVM поддержку оператора goto
. Однако впоследствии эту фичу выпorли. Одна из причин заключается в том, что блоки codeа содержащие оператор goto
, читались не так хорошо, How блоки codeа, выполняющие те же функции, но без goto
, а с альтернативными подходами (break
, continue
, вынесение блока codeа в методы). Были, собственно и другие, How например:
- сложность чтения и понимания codeа, в котором есть операторы
goto
; - усложнение оптимизации codeа компилятору (а иногда и невозможность);
- повышение вероятности создания трудно уловимых ошибок в codeе.
goto
вполне успешно функционирует. Однако программисты избегают его использование. Почитать о причинах этого можно в одной статье на хабре. Но зачем тогда оставлять goto
в списке зарезервированных слов? Все просто: на будущее. Если, к примеру, по всему миру в codeе Java разработчиков переменные, методы or классы будут называться goto
, если этот оператор вернут в одной из будущих версий Java, весь старый code сломается. Whatбы избежать такого сценария, goto
остался в списке ключевых слов Java, но не несет в себе ниHowой функциональности. Возможно когда-нибудь goto
вернется в наши ряды, но вероятность этого невысока.
Итоги
Мы рассмотрели различные операторы перехода в Java:return
— завершение метода, возвращение значения из метода.- с возвращаемым meaningм: методы, которые возвращают значения;
- без возвращаемого значения:
void
методы.
break
— прерывание циклов, switch-case блоки.- с метками: циклы различной вложенности;
- без меток: ветки switch-case блока; прерывание цикла, в котором был вызван.
continue
.- с метками: циклы различной вложенности;
- без меток: продолжение цикла, в котором был вызван.
goto
.- есть в списке ключевых слов, но не используется.
GO TO FULL VERSION