Bonjour! Aujourd'hui, nous allons parler des opérateurs de saut en Java :
return
break
continue
goto
if
) et des boucles ( for
, while
etc.). En plus des constructions de contrôle, l'exécution linéaire d'un programme peut être modifiée par des instructions de saut. Ils sont chargés de rediriger l'exécution du programme vers un emplacement spécifique, qui dépend du contexte et de l'instruction spécifique. Examinons de plus près chacun des quatre opérateurs.
retour
C'est cet opérateur que les nouveaux arrivants connaissent le plus souvent en premier. L'instructionreturn
termine la méthode dans laquelle elle a été appelée et l'exécution du programme revient à l'emplacement à partir duquel la méthode a été appelée. Il return
a deux formes :
- Termine immédiatement l'exécution de la méthode.
- Termine immédiatement l'exécution de la méthode et renvoie une valeur comme résultat de la méthode.
return;
return value; // где value — некоторое возвращаемое meaning
Les méthodes qui renvoient une valeur doivent avoir au moins un opérateur return
avec une valeur de retour dont l'appel est garanti, et ne doivent pas avoir d'opérateur return
sans valeur de retour. Regardons les exemples ci-dessous :
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;
}
}
Dans les méthodes qui ne renvoient pas de valeur (methods void
), il est acceptable, mais pas obligatoire, d'avoir au moins une instruction return
sans valeur de retour, et pas une seule instruction return
avec une valeur de retour. Regardons cela avec les exemples ci-dessous :
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);
}
Étiquettes
Avant de regarder les opérateursbreak
et continue
, je voudrais parler des étiquettes en Java. Ceci est important car dans certaines situations, break
les opérateurs continue
sont utilisés conjointement avec les étiquettes. Mais d’abord, essayez de répondre à la question de savoir si ce code sera compilé :
public static void main(String[] args) {
https://www.google.com/
System.out.println("Interesting...");
}
Une étiquette est un morceau de code nommé. L'étiquette elle-même ne fournit aucune fonctionnalité. C'est quelque chose comme un signet dans le code que le programmeur a l'intention d'utiliser plus tard. Une étiquette dans le code est définie assez simplement - via un nom et deux points. Par exemple:
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();
}
}
Le résultat de la méthode main
sera le suivant :
Таблица Умножения
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
Dans l'exemple ci-dessus definePrintName
, loop1:
et loop2:
sont des étiquettes. loop1:
et loop2:
"marquer" deux cycles - externe et interne. Nous examinerons l'utilisation des étiquettes dans la section ci-dessous. En attendant, si vous avez répondu « non » à la question de savoir si ce code sera compilé :
public static void main(String[] args) {
https://www.google.com/
System.out.println("Interesting...");
}
Essayez d'y répondre à nouveau en utilisant l'IDE.
casser
L'opérateurbreak
est utilisé dans deux cas :
- Pour terminer n’importe quelle branche d’exécution dans un bloc switch-case.
- Pour interrompre l'exécution d'une boucle.
break labelName; // Синтаксис оператора с меткой
break; // Синтаксис оператора без метки
Dans les blocs de commutation, l'opérateur break
est utilisé sans étiquettes :
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);
}
Dans les boucles, une instruction break
est utilisée pour interrompre d’autres itérations une fois que certaines conditions sont remplies. Cela peut souvent se produire lorsque vous devez parcourir un tableau ou une collection d'éléments et y trouver un élément qui satisfait aux conditions nécessaires. Considérons cet exemple. Nous avons un tableau et nous devons déterminer si le tableau contient des éléments négatifs :
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;
}
}
Regardons le même exemple avec différentes boucles. Faire du vélo 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;
}
}
}
Faire du vélo 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 ++;
}
}
Faire du vélo 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);
}
Un autre exemple d'instruction break
en boucle consiste à interrompre une boucle infinie lorsque certaines conditions sont remplies. Voici un exemple de programme qui affiche la ligne saisie par l'utilisateur jusqu'à ce que l'utilisateur saisisse le mot « 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);
}
}
Considérons l'utilisation de l'opérateur break
avec une étiquette. Une interruption avec une étiquette est utilisée dans les cas comportant plusieurs cycles, de plus, imbriqués les uns dans les autres. Dans ce cas, l'un des cycles (ou tous les cycles) est marqué d'une étiquette. Ensuite, l'opérateur, break
en indiquant l'étiquette, interrompt le cycle souhaité. Considérons un exemple dans lequel nous devons comprendre s'il y a un élément négatif, mais pas dans le tableau, mais dans la matrice :
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;
}
}
}
}
continuité
L'opérateurcontinue
dispose également de deux formulaires - avec et sans étiquette :
continue; // форма оператора без метки
continue labelName; // форма оператора с меткой
Contrairement à l'opérateur break
, qui interrompt toutes les itérations restantes de la boucle, l'opérateur continue
interrompt l'itération en cours et provoque le démarrage de la suivante. Cela peut être utile si vous devez effectuer certaines opérations sur des éléments qui satisfont certaines conditions. Disons que nous avons une chaîne et que nous voulons compter le nombre de mots commençant par la lettre « m » :
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);
}
Après avoir exécuté ce code, la sortie suivante apparaîtra dans la console :
Кол-во слов, начинающихся с буквы М в предложении: [Мама мыла раму] = 2
L'opérateur continue
ainsi que l'étiquette sont également utilisés lors de l'itération sur des éléments. Imaginons une matrice dans laquelle nous devons compter le nombre de lignes avec des éléments négatifs :
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);
}
Le résultat de ce code sera :
Rows With Negative Elements Count = 3
Il faut dire que les opérateurs break
, continue
et return
peuvent être utilisés de différentes manières pour obtenir la même fonctionnalité. Ainsi, vous pouvez réécrire le dernier exemple et continue
utiliserbreak
:
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);
}
La différence entre break
et continue
avec une étiquette est ce qui break
complète les itérations de la boucle dans laquelle elle est écrite. Et continue
avec une étiquette, saute l'itération en cours du cycle marqué par l'étiquette. Dans certaines situations, vous pouvez remplacer l'un par l'autre et toutes les fonctionnalités du programme resteront les mêmes. Nous parlerons ci-dessous de ce qu’il est préférable de choisir (spoiler : lisibilité du code). L'opérateur break
peut être remplacé non seulement par continue
par une étiquette, mais également par return
. Juste avant cela, vous devez déplacer la boucle imbriquée dans une méthode distincte :
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;
}
Il y a plein de façons d'écrire la même chose. Lequel choisir ? En programmation industrielle, cette question est résolue par la facilité de compréhension du code. Plus c’est écrit simplement, mieux c’est. Plus il y a de boucles imbriquées, plus il est difficile de percevoir le code. Surtout si les boucles sont marquées avec des étiquettes différentes, qui sont utilisées dans les interruptions et les continuations ( break
et continue
). S'il est possible de ne pas utiliser de balises, il vaut mieux le faire. Sinon, essayez d’écrire aussi clairement et joliment que possible.
aller à
Dans certains langages de programmation, il existe un opérateurgoto
. Généralement, il redirige l'exécution du code vers une partie du programme marquée d'une étiquette. Mais en Java goto
, pourrait-on dire, c'est le cas et ce n'est pas le cas. Voyons cela. La liste des mots-clés en Java inclut le mot goto
. Cependant, cette déclaration est marquée comme non utilisée. Le fait est que James Gosling, le créateur du langage Java, a initialement inclus la prise en charge de l'opérateur dans la JVM goto
. Cependant, cette fonctionnalité a été supprimée par la suite. L'une des raisons est que les blocs de code contenant l'opérateur goto
n'étaient pas aussi lisibles que les blocs de code qui remplissaient les mêmes fonctions mais sans goto
, mais avec des approches alternatives ( break
, continue
, en plaçant le bloc de code dans des méthodes). Il y en avait en effet d’autres, comme :
- difficulté à lire et à comprendre le code contenant des opérateurs
goto
; - compliquer l'optimisation du code pour le compilateur (et parfois même impossible) ;
- augmentant la probabilité de créer des erreurs subtiles dans le code.
goto
fonctionne avec beaucoup de succès. Cependant, les programmeurs évitent de l’utiliser. Vous pouvez en découvrir les raisons dans un article sur Habré . Mais pourquoi alors le laisser goto
sur la liste des mots réservés ? C'est simple : pour l'avenir. Si, par exemple, des variables, des méthodes ou des classes sont appelées dans le code Java des développeurs du monde entier goto
, si cette instruction est renvoyée dans une future version de Java, tout l'ancien code sera interrompu. Pour éviter un tel scénario, goto
il reste dans la liste des mots-clés Java, mais n'emporte aucune fonctionnalité. Peut-être qu'un jour goto
il reviendra dans nos rangs, mais la probabilité que cela se produise est faible.
Résultats
Nous avons examiné différents opérateurs de saut en Java :return
— achèvement de la méthode, renvoyant une valeur de la méthode.- avec une valeur de retour : méthodes qui renvoient des valeurs ;
- aucune valeur de retour :
void
méthodes.
break
— interruption des cycles, blocs de boîtiers de commutation.- avec balises : cycles d'imbrications diverses ;
- sans étiquettes : branches d'interrupteur du bloc ; interrompant la boucle dans laquelle il a été appelé.
continue
.- avec balises : cycles d'imbrications diverses ;
- sans étiquettes : continuation de la boucle dans laquelle il a été appelé.
goto
.- est dans la liste des mots-clés, mais n'est pas utilisé.
GO TO FULL VERSION