Ciao! Oggi parleremo degli operatori di salto in Java:
return
break
continue
goto
if
) e cicli ( for
, while
ecc.). Oltre ai costrutti di controllo, l'esecuzione lineare di un programma può essere modificata mediante istruzioni di salto. Sono responsabili del reindirizzamento dell'esecuzione del programma in una posizione specifica, che dipende dal contesto e dall'istruzione specifica. Diamo uno sguardo più da vicino a ciascuno dei quattro operatori.
ritorno
È con questo operatore che i nuovi arrivati spesso acquisiscono familiarità per primi. L'istruzionereturn
termina il metodo in cui è stata chiamata e l'esecuzione del programma ritorna alla posizione da cui è stato chiamato il metodo. Ha return
due forme:
- Termina immediatamente l'esecuzione del metodo.
- Termina immediatamente l'esecuzione del metodo e restituisce un valore come risultato del metodo.
return;
return value; // где value — некоторое возвращаемое meaning
I metodi che restituiscono un valore devono avere almeno un operatore return
con un valore restituito di cui è garantito che venga chiamato e non devono avere un operatore return
senza un valore restituito. Diamo un'occhiata agli esempi seguenti:
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;
}
}
Nei metodi che non restituiscono un valore (metodi void
), è accettabile, ma non obbligatorio, avere almeno un'istruzione return
senza valore restituito e non una singola istruzione return
con un valore restituito. Diamo un'occhiata a questo con gli esempi seguenti:
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);
}
etichette
Prima di esaminare gli operatoribreak
and continue
, vorrei parlare delle etichette in Java. Questo è importante perché in alcune situazioni gli operatori break
e continue
vengono utilizzati insieme alle etichette. Ma prima, prova a rispondere alla domanda se questo codice verrà compilato:
public static void main(String[] args) {
https://www.google.com/
System.out.println("Interesting...");
}
Un'etichetta è un pezzo di codice con nome. L'etichetta stessa non fornisce alcuna funzionalità. Questo è qualcosa come un segnalibro nel codice che il programmatore intende utilizzare in seguito. Un'etichetta nel codice viene definita in modo molto semplice: tramite un nome e due punti. Per esempio:
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();
}
}
L'output del metodo main
sarà il seguente:
Таблица Умножения
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
Nell'esempio sopra definePrintName
, loop1:
e loop2:
sono etichette. loop1:
e loop2:
“segnare” due cicli: esterno e interno. Vedremo l'utilizzo delle etichette nella sezione seguente. Nel frattempo, se hai risposto "no" alla domanda se questo codice verrà compilato:
public static void main(String[] args) {
https://www.google.com/
System.out.println("Interesting...");
}
Prova a rispondere di nuovo, utilizzando l'IDE.
rottura
L'operatorebreak
viene utilizzato in due casi:
- Per completare qualsiasi ramo di esecuzione in un blocco switch-case.
- Per interrompere l'esecuzione di un loop.
break labelName; // Синтаксис оператора с меткой
break; // Синтаксис оператора без метки
Nei blocchi di interruttori l'operatore break
viene utilizzato senza etichette:
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);
}
Nei cicli, un'istruzione break
viene utilizzata per interrompere ulteriori iterazioni dopo che sono soddisfatte determinate condizioni. Questo può essere spesso trovato quando è necessario scorrere un array o una raccolta di elementi e trovare qualche elemento al suo interno che soddisfi le condizioni necessarie. Consideriamo questo esempio. Abbiamo un array e dobbiamo determinare se l'array contiene elementi negativi:
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;
}
}
Diamo un'occhiata allo stesso esempio con loop diversi. Ciclo 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;
}
}
}
Ciclo 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 ++;
}
}
Ciclo 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 altro esempio di istruzione break
in loop è interrompere un loop infinito quando vengono soddisfatte determinate condizioni. Ecco un esempio di un programma che visualizza la riga inserita dall'utente finché l'utente non inserisce la parola "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);
}
}
Consideriamo l'utilizzo dell'operatore break
insieme a un'etichetta. Un'interruzione con etichetta viene utilizzata nei casi con più cicli, per di più annidati uno nell'altro. In questo caso uno dei cicli (o tutti i cicli) è contrassegnato da un'etichetta. Successivamente l'operatore, break
contestualmente all'indicazione dell'etichetta, interrompe il ciclo desiderato. Consideriamo un esempio in cui dobbiamo capire se c'è un elemento negativo, ma non nell'array, ma nella 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'operatorecontinue
ha anche due moduli: con e senza etichetta:
continue; // форма оператора без метки
continue labelName; // форма оператора с меткой
A differenza dell'operatore break
, che interrompe tutte le restanti iterazioni del ciclo, l'operatore continue
interrompe l'iterazione corrente e fa iniziare quella successiva. Ciò può essere utile se è necessario eseguire alcune operazioni su elementi che soddisfano determinate condizioni. Diciamo di avere una stringa e di voler contare il numero di parole che iniziano con la lettera "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);
}
Dopo aver eseguito questo codice ci sarà il seguente output nella console:
Кол-во слов, начинающихся с буквы М в предложении: [Мама мыла раму] = 2
L'operatore continue
insieme all'etichetta viene utilizzato anche durante l'iterazione sugli elementi. Immaginiamo una matrice in cui dobbiamo contare il numero di righe con elementi negativi:
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);
}
L'output di questo codice sarà:
Rows With Negative Elements Count = 3
Vale la pena dire che gli operatori break
, continue
e return
possono essere utilizzati in modi diversi per ottenere la stessa funzionalità. Quindi, puoi riscrivere l'ultimo esempio e continue
utilizzare 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);
}
La differenza tra break
e continue
con un'etichetta è ciò che break
completa le iterazioni del ciclo in cui è scritta. E continue
con un'etichetta, salta l'iterazione corrente del ciclo contrassegnato con l'etichetta. In alcune situazioni, puoi sostituirne uno con l'altro e tutto nella funzionalità del programma rimarrà lo stesso. Parleremo di cosa è meglio scegliere (spoiler: leggibilità del codice) di seguito. L'operatore break
può essere sostituito non solo con continue
un'etichetta, ma anche con return
. Poco prima è necessario spostare il ciclo annidato in un metodo separato:
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;
}
Molti modi per scrivere la stessa cosa. Quale scegliere? Nella programmazione industriale, questo problema è deciso dalla facilità di comprensione del codice. Più è scritto in modo semplice, meglio è. Più cicli sono annidati, più difficile è percepire il codice. Soprattutto se i loop sono contrassegnati con etichette diverse, che vengono utilizzate nelle interruzioni e nelle continuazioni ( break
e continue
). Se è possibile non utilizzare i tag è meglio farlo. Altrimenti, prova a scrivere nel modo più chiaro e bello possibile.
vai a
In alcuni linguaggi di programmazione è presente un operatoregoto
. In genere reindirizza l'esecuzione del codice ad alcune parti del programma contrassegnate da un'etichetta. Ma in Java goto
, si potrebbe dire, lo è e non lo è. Scopriamolo. L'elenco delle parole chiave in Java include la parola goto
. Tuttavia, questa istruzione è contrassegnata come non utilizzata. Il fatto è che James Gosling, il creatore del linguaggio Java, inizialmente incluse il supporto per l'operatore nella JVM goto
. Tuttavia, questa funzionalità è stata successivamente eliminata. Uno dei motivi è che i blocchi di codice contenenti l'operatore goto
non erano leggibili come i blocchi di codice che eseguivano le stesse funzioni ma senza goto
, ma con approcci alternativi ( break
, continue
, inserendo il blocco di codice nei metodi). Ce n'erano infatti altri, come:
- difficoltà nella lettura e comprensione del codice che contiene operatori
goto
; - complicare l'ottimizzazione del codice per il compilatore (e talvolta addirittura impossibile);
- aumentando la probabilità di creare errori sottili nel codice.
goto
funzioni con successo. Tuttavia, i programmatori evitano di usarlo. Puoi leggere le ragioni di ciò in un articolo su Habré . Ma allora perché lasciarlo goto
nell'elenco delle parole riservate? È semplice: per il futuro. Se, ad esempio, vengono chiamate variabili, metodi o classi nel codice Java degli sviluppatori di tutto il mondo goto
, se questa istruzione viene restituita in una futura versione di Java, tutto il vecchio codice si romperà. Per evitare uno scenario del genere, goto
rimane nell'elenco delle parole chiave Java, ma non presenta alcuna funzionalità. Forse un giorno goto
tornerà tra noi, ma la probabilità che ciò accada è bassa.
Risultati
Abbiamo esaminato vari operatori di salto in Java:return
— completamento del metodo, restituendo un valore dal metodo.- con un valore restituito: metodi che restituiscono valori;
- nessun valore restituito:
void
metodi.
break
— interruzione dei cicli, blocco dei quadri.- con tag: cicli di annidamento vario;
- senza etichette: rami del quadro del blocco; interrompendo il ciclo in cui è stato chiamato.
continue
.- con tag: cicli di annidamento vario;
- senza etichette: continuazione del ciclo in cui è stato chiamato.
goto
.- è nell'elenco delle parole chiave, ma non viene utilizzato.
GO TO FULL VERSION