Ricerca nel sito web

Come scrivere istruzioni condizionali in Java


L'autore ha selezionato il programma Write for DOnations.

introduzione

Le istruzioni condizionali modificano il flusso del programma. Le istruzioni condizionali sono anche chiamate istruzioni di ramificazione perché quando una condizione viene soddisfatta, il flusso va in una direzione in un ramo del codice. Se una condizione non è soddisfatta, viene valutata un'altra condizione (se presente). Questa valutazione continua finché tutte le condizioni non vengono valutate su true o false. Ad esempio, puoi confrontare due numeri (x e y) con le seguenti istruzioni condizionali: x > y, x=y e x < y. Se x è uguale a 1 e y è uguale a 2, ci saranno tre valutazioni fino alla x < finale y istruzione condizionale restituisce true.

Ci sono due tipi di condizionali. Il primo tipo è if e le sue varianti estese else if. Questo tipo è ampiamente utilizzato. Il secondo tipo è switch, che è più specifico e limitato.

In questo tutorial, scriverai istruzioni condizionali in Java e imparerai i casi d'uso, i vantaggi e gli svantaggi di ogni tipo.

Prerequisiti

Per seguire questo tutorial, avrai bisogno di:

  • Un ambiente in cui è possibile eseguire programmi Java da seguire insieme agli esempi. Per configurarlo sul tuo computer locale, avrai bisogno di quanto segue:
    • Java (versione 11 o successiva) installato sulla tua macchina, con il compilatore fornito dal Java Development Kit (JDK). Per Ubuntu e Debian, segui i passaggi per le opzioni di download per l'installazione di Java.
    • Per compilare ed eseguire gli esempi di codice, questo tutorial utilizza la guida Introduzione alla JShell.

    Familiarità con Java e programmazione orientata agli oggetti, che puoi trovare nel nostro tutorial, Come scrivere il tuo primo programma in Java.

    Una comprensione dei tipi di dati Java, discussa nel nostro tutorial, Comprensione dei tipi di dati in Java

    Differenziazione tra istruzioni e blocchi

    Quando viene soddisfatta un'istruzione condizionale e il flusso di esecuzione viene indirizzato a un ramo di codice corrispondente, questo ramo potrebbe essere una singola istruzione o un blocco di codice. Le istruzioni e i blocchi di codice vengono elaborati in modo diverso, quindi è importante distinguerli.

    Una istruzione è una singola unità di esecuzione, di solito su una riga, terminata con un punto e virgola. Ad esempio, utilizza la seguente istruzione per stampare example:

    1. System.out.println("example");

    Informazioni: per seguire il codice di esempio in questo tutorial, apri lo strumento Java Shell sul tuo sistema locale eseguendo il comando jshell. Quindi puoi copiare, incollare o modificare gli esempi aggiungendoli dopo il prompt jshell> e premendo INVIO. Per uscire da jshell, digita /exit.

    Questa istruzione usa il metodo println() per stampare una stringa, che in questo caso è example. Se non diversamente indicato, Java eseguirà questa istruzione incondizionatamente.

    Nota:

    Inoltre, in alcuni casi, come con le espressioni lambda, è più comodo e intuitivo distribuire le istruzioni su poche righe. In ogni caso, Java non impone requisiti di sintassi sulle nuove righe in un'istruzione e puoi semplicemente continuare l'istruzione su una nuova riga. Come esercizio, prova a riscrivere alcuni degli esempi di questo tutorial e separa le istruzioni su più righe.

    Quando raggruppi le istruzioni in modo che vengano eseguite insieme, stai utilizzando un blocco. Un blocco è un gruppo di zero o più istruzioni che inizia con una parentesi aperta ({) e termina con una parentesi chiusa (}). Puoi riscrivere il codice precedente e inserirlo all'interno di un blocco come questo:

    1. {
    2. System.out.println("example");
    3. }

    Nel blocco sopra, hai usato quattro spazi prima di System.out.println(example);. Questi quattro spazi sono chiamati rientro. A differenza di altri linguaggi di programmazione come Python, l'indentazione in Java non è richiesta e non influisce sul codice. Tuttavia, per una migliore leggibilità e per convenzione, le righe all'interno di un blocco iniziano con un rientro di quattro spazi. La maggior parte degli editor di codice supporta il rientro automatico, ma la convenzione è diversa tra i linguaggi di programmazione e persino tra gli editor. Pertanto, se il tuo editor di codice supporta il rientro, assicurati che sia impostato su quattro spazi durante la scrittura del codice Java. Jshell, consigliato e utilizzato in questo tutorial, imposta automaticamente quattro spazi come indentazione.

    In questo caso inserire il codice all'interno di un blocco non fa differenza perché non ci sono condizioni. Pertanto, example verrà stampato indipendentemente dal fatto che l'istruzione sia all'interno di un blocco. Quando esegui i due esempi precedenti in jshell, riceverai lo stesso output in entrambi i casi:

    Output
    example

    L'output precedente mostra che l'istruzione per la stampa di example funziona allo stesso modo sia all'interno di un blocco che al di fuori di esso.

    In questa sezione, hai imparato le istruzioni, i blocchi e come crearli. Nella sezione successiva, aggiungerai un'istruzione condizionale a un blocco di codice. Pertanto, le istruzioni all'interno del blocco verranno eseguite insieme e in modo condizionale.

    Utilizzo di condizioni condizionali singole

    L'istruzione condizionale più comunemente usata è l'istruzione if. È universale e si adatta a ogni esigenza di confronto condizionale, purché il risultato del confronto sia un valore booleano (true o false). Il condizionale if può essere un singolo condizionale nella sua forma più semplice o avere una struttura più complessa, che utilizzerai nelle sezioni successive.

    La singola istruzione if è usata per eseguire una parte di codice sotto una singola condizione. Metterai il codice eseguito in modo condizionale all'interno di un blocco e metterai if (espressione booleana) all'inizio. Se l'espressione, e quindi la condizione, è true, solo allora il blocco di codice verrà eseguito. Se l'espressione restituisce false, il codice del blocco condizionale verrà saltato.

    In questo esempio, scriverai uno snippet di codice che confronta due numeri. A seconda del risultato del confronto, potrebbe essere stampato un messaggio. Aggiungi le seguenti righe a jshell:

    1. int x = 1;
    2. int y = 0;
    3. if (x > y) {
    4. System.out.println(x + " is bigger than " + y);
    5. }

    Definisci due variabili nelle prime due righe: x e y. La terza riga è il condizionale if (x > y), che confronta se x è maggiore di y. Il confronto è sempre tra parentesi.

    Il codice del blocco inizia con la prima parentesi aperta ({) e termina con la parentesi chiusa (}). All'interno del blocco, un'istruzione utilizza il metodo println() per stampare che x è maggiore di y. Il codice del blocco verrà eseguito solo se questa condizione è true.

    Quando esegui questo codice in jshell, otterrai il seguente output:

    Output
    x ==> 1 y ==> 0 1 is bigger than 0

    Le prime due righe dell'output confermano i valori di x e y. La riga 3 legge 1 è maggiore di 0, il che significa che l'istruzione condizionale è true: x è maggiore di y >. Se modifichi x in modo che sia più piccolo di y, il messaggio non verrà stampato.

    La regola più importante nelle istruzioni condizionali è che l'espressione valutata deve restituire un booleano. In ogni altro caso, riceverai un errore che indica che ciò che stai confrontando non può essere convertito in un booleano.

    Per ulteriore pratica, prova a causare un errore con un'espressione non booleana. Per fare ciò, inserisci una variabile int, che non può essere convertita in boolean, all'interno delle parentesi condizionali come questa:

    1. int x = 1;
    2. if (x) {
    3. System.out.println("Will this work?");
    4. }

    Nella riga 1, definisci una variabile int x e le assegni un valore (1). La riga 2 è la condizione if (x), che bloccherà il programma perché x non può essere convertito in un valore booleano. Quando esegui il codice precedente in jshell, otterrai il seguente errore:

    Output
    x ==> 1 | Error: | incompatible types: int cannot be converted to boolean | if (x) { | ^

    La prima riga conferma che x ha ricevuto il valore 1. Le righe successive descrivono l'errore sui tipi incompatibili e spiegano che un valore int come x non può essere convertito in un boolean codice> valore. Ogni volta che ricevi un errore del genere, saprai ricontrollare il confronto.

    Un'istruzione condizionale non booleana come questa è probabilmente la trappola più comune con i condizionali. Fortunatamente, i moderni IDE (Integration Development Environments) rilevano tali errori mentre scrivi. Tuttavia, anche se non utilizzi un IDE, gli errori sono evidenti.

    Scrivere istruzioni if condizionali senza un blocco

    Una particolarità dei condizionali if di Java è che esiste un modo più breve per scriverli senza utilizzare un blocco di codice. Sebbene non sia consigliabile utilizzare condizionali senza un blocco di codice, dovresti sapere che è possibile scrivere codice come questo. Dal punto di vista pratico, se studi per un esame Java o vai a un colloquio di lavoro, potresti incontrare esempi così confusi e dovresti essere preparato.

    Ad esempio, invece di utilizzare un blocco di codice, potresti scrivere un'istruzione come questa:

    1. int x = 1;
    2. int y = 0;
    3. if (x > y)
    4. System.out.println(x + " is bigger than " + y);

    La differenza rispetto all'esempio precedente è che non c'è nessun blocco di codice dopo l'istruzione condizionale if (x > y). Invece, l'istruzione di destinazione System.out.println(x + è maggiore di + y) viene immediatamente dopo l'istruzione condizionale if (x > y).

    Quando lo esegui in jshell, otterrai lo stesso output dell'esempio precedente:

    Output
    x ==> 1 y ==> 0 1 is bigger than 0

    I valori di x e y verranno stampati nelle prime due righe. Il messaggio di conferma che 1 è maggiore di 0 viene stampato sulla riga 3.

    Quando non c'è codice a blocchi che segue un condizionale, solo la riga immediatamente dopo il condizionale dipende dal condizionale. In questo caso, qualsiasi istruzione dopo la riga 4 verrà eseguita indipendentemente dal condizionale. Ad esempio, prova a cambiare x in 0, in modo che non sia più grande di y, e aggiungi una quinta riga in questo modo:

    1. int x = 0;
    2. int y = 0;
    3. if (x > y)
    4. System.out.println(x + " is bigger than " + y);
    5. System.out.println("This line is always printed.");

    Quando esegui il codice precedente in jshell, otterrai il seguente output:

    Output
    x ==> 0 y ==> 0 This line is always printed.

    I valori di x e y sono stampati sulle righe 1 e 2. Entrambi i valori sono 0, il che significa che sono uguali. Per questo motivo, l'istruzione condizionale x > y restituisce false. Pertanto, la quarta riga che dice x è maggiore di y non viene stampata. Tuttavia, la riga 5 viene stampata perché la sua esecuzione non dipende dal condizionale.

    Inoltre, il rientro alla riga 5 non è necessario. È stato incluso per suggerire che l'esecuzione della riga 5 dipende dal condizionale, il che non è il caso. Questo trattino potrebbe essere omesso, ma ciò non renderebbe il codice più chiaro.

    L'uso di condizionali senza un blocco di codice non è intuitivo o facile da seguire, motivo per cui dovresti usare la sintassi abbreviata con parsimonia. Per mantenere il tuo codice pulito e comprensibile, è meglio utilizzare istruzioni di blocco perché sono più leggibili e ti consentono di avere più di una riga di codice eseguito in modo condizionale.

    Le istruzioni if nidificate sono un altro esempio di codice che è possibile scrivere ma di solito non consigliato. Nella sezione successiva, esplorerai le istruzioni if nidificate per comprenderne meglio il valore e gli svantaggi.

    Nidificazione delle istruzioni If

    Per creare una struttura condizionale più complessa, è possibile combinare molte istruzioni if. Per creare istruzioni if nidificate, inserisci un'altra istruzione if all'interno di un'istruzione if principale invece che in un blocco di codice.

    Questa pratica di solito non è consigliata poiché rende il codice più difficile da leggere e comprendere. Tuttavia, le istruzioni if annidate a volte hanno un uso pratico, quindi è utile conoscerle.

    Per capire come si fa, estenderai l'esempio precedente aggiungendo un'altra istruzione if. Confronterai di nuovo y per valutare se è uguale a 0. Aggiungi le seguenti righe a jshell:

    1. int x = 1;
    2. int y = 0;
    3. if (x > y) {
    4. if (y == 0) {
    5. System.out.println("This is legal but does not look clean.");
    6. }
    7. }

    Le prime tre righe rimangono invariate rispetto agli esempi precedenti: definisci due variabili int (x e y) e le confronti. Alla riga 4, un'altra istruzione if confronta se y è uguale a 0. Se true, Java procederà con la riga 5, che ha un'istruzione println() con il messaggio Questo è legale ma non sembra pulito. .

    Quando lo esegui in jshell, otterrai il seguente output:

    Output
    x ==> 1 y ==> 0 This is legal but does not look clean.

    Le prime due righe confermano i valori di x e y. La riga 3 recita Questo è legale ma non sembra pulito.. Questo messaggio conferma che il codice del blocco è stato eseguito perché entrambe le condizioni if sono soddisfatte: x > y e y == 0.

    Puoi annidare istruzioni if come questa all'infinito. Tuttavia, con ogni istruzione if nidificata, aumenti la complessità del codice e ne diminuisci la leggibilità. Ecco perché l'annidamento delle istruzioni if non è generalmente considerato una buona pratica di codifica.

    Tuttavia, le strutture condizionali annidate hanno qualche utilità pratica. A volte, può sembrare utile sacrificare la leggibilità e aumentare la complessità a favore della scrittura di codice più breve e del potenziale risparmio di tempo. Di conseguenza, potresti incontrare dichiarazioni nidificate durante gli esami, i colloqui di lavoro o nel codice produttivo del mondo reale.

    Utilizzo di condizionali If estesi con istruzioni Else If e Else

    I condizionali if possono essere ulteriormente estesi per gestire ulteriori criteri di corrispondenza usando istruzioni supplementari else if e else. Le istruzioni else possono essere utilizzate solo dopo un'istruzione if iniziale. Con else if, puoi aggiungere illimitate istruzioni condizionali aggiuntive, simili al primo if. Con un else finale, facoltativo, specifichi il percorso predefinito che il flusso del programma dovrebbe seguire nel caso in cui non sia stata trovata alcuna corrispondenza condizionale precedente.

    Con else if e else, puoi diramare il flusso del tuo programma in più direzioni rispetto al singolo if. Pertanto, puoi costruire strutture condizionali complesse che non possono essere costruite in nessun altro modo. La ramificazione del codice in varie direzioni consente di gestire casi aziendali più complessi. Tuttavia, i requisiti aziendali nella produzione sono numerosi e il flusso di progettazione non è necessariamente lineare.

    Inizia con il seguente esempio di codice per avere un'idea delle istruzioni else if e else. Estenderai il codice utilizzato in precedenza e aggiungerai altri rami condizionali. Queste nuove condizioni continueranno a confrontare x e y:

    1. int x = 1;
    2. int y = 0;
    3. if (x > y) {
    4. System.out.println(x + " is bigger than " + y);
    5. } else if (x < y) {
    6. System.out.println(y + " is bigger than " + x);
    7. } else if (x == y) {
    8. System.out.println(x + " is equal to " + y);
    9. } else {
    10. System.out.println(x + " cannot be compared to " + y);
    11. }

    Secondo il codice sopra, le righe 1 e 2 definiscono due variabili (x e y) con i valori 1 e 0. Nelle righe 3 e 4, valuti se x è maggiore di y con un'istruzione if. Se la valutazione è true, verrà stampato il testo x è più grande di y e si uscirà dalla struttura condizionale. Se la valutazione è false, il programma continuerà con il condizionale successivo. Finora, il codice è lo stesso degli esempi precedenti.

    Alla riga 5, dopo la parentesi di chiusura dell'istruzione if, c'è un'istruzione else if. Ha una sintassi simile a un if: c'è un'espressione booleana tra parentesi e un blocco di codice che segue. L'espressione valuta se y è maggiore di x, che è l'opposto della precedente istruzione if. Se l'espressione è true, il blocco di codice che la segue verrà eseguito e di nuovo la struttura condizionale verrà chiusa. In questo caso, questa è l'istruzione alla riga 6, che stamperà y è maggiore di x.

    Alla riga 7 c'è un altro caso else if. Questa volta, controlli se x è uguale a y tra parentesi. Se true, l'istruzione alla riga 8 verrà eseguita e stamperà x è uguale a y. Tali istruzioni else if possono essere aggiunte indefinitamente, una dopo l'altra e valutando diverse condizioni.

    Alla riga 9 c'è l'istruzione else finale. È sempre finale e non ha una condizione, il che significa che il suo ramo viene sempre inserito se non è stata trovata corrispondenza con nessun'altra istruzione condizionale. In altre parole, il blocco di codice dopo else viene eseguito quando nessuna condizione if o else if è stata precedentemente soddisfatta. Se questo fosse true, verrebbe eseguito il codice alla riga 10, stampando che x non può essere confrontato con y.

    Solo la prima istruzione if è richiesta in strutture condizionali così complesse. Se desideri effettuare ulteriori confronti, puoi avere zero o più istruzioni else if. Alla fine, puoi inserire un else facoltativo da abbinare se nessun altro condizionale ha trovato corrispondenza.

    Quando esegui il codice precedente in jshell, otterrai il seguente output:

    Output
    x ==> 1 y ==> 0 1 is bigger than 0

    La prima e la seconda riga dell'output precedente confermano i valori di x e y: 1 e 0. La terza riga stampa 1 è maggiore di 0, il che conferma che l'espressione booleana (x > y) ha restituito true e il codice del blocco dopo che è stata eseguita.

    Scrivere istruzioni if, else if e else è un buon modo per scrivere strutture condizionali complesse perché puoi inserire condizioni diverse in ogni istruzioni if e else if. Nell'esempio precedente, prima hai confrontato x > y, poi l'opposto x < y e infine x == y. Il codice è ancora leggibile e gestibile nei casi con pochi confronti.

    Tuttavia, se hai bisogno di fare più confronti, l'aggiunta di più istruzioni else if renderà il codice difficile da seguire e persino confuso. Ecco perché dovresti rendere le tue strutture piccole e semplici quando possibile. Inoltre, in alcuni casi, esiste un'alternativa a tali strutture complesse utilizzando l'istruzione switch, che utilizzerai nella prossima sezione.

    Utilizzo di condizionali di commutazione

    L'istruzione switch è un'altra istruzione condizionale che puoi usare per costruire strutture decisionali. È simile a un'istruzione if perché può essere utilizzata per dirigere il flusso del programma in modo condizionale. Tuttavia, l'istruzione switch funziona con una singola variabile e la confronta con diversi casi predefiniti. Pertanto, non puoi valutare espressioni booleane come x > y. Invece, puoi avere, per esempio, una variabile int e confrontarne il valore con altre variabili int; quando c'è una corrispondenza (ovvero, un caso), il flusso del programma verrà reindirizzato in base alla corrispondenza.

    I condizionali switch hanno due regole importanti. Il primo è che la variabile confrontata può essere solo di tipi di dati specifici, come i tipi primitivi int e char, così come i tipi di riferimento String e Intero. (L'elenco completo dei tipi di dati supportati può essere trovato nella documentazione ufficiale di switch.) Pertanto, non è possibile utilizzare variabili boolean, motivo per cui switch I condizionali non possono sostituire i condizionali if.

    L'altra regola importante è che i valori per le istruzioni case devono essere Costanti simili a variabili, ma hanno la parola chiave final davanti quando vengono definite. A differenza delle variabili, non è possibile modificare il valore di una costante una volta definita. Le costanti saranno trattate in dettaglio nei futuri tutorial della nostra serie Java.

    La struttura switch è più limitata della struttura if e non la sostituisce completamente. Tuttavia, ha il vantaggio unico di essere più leggibile e più adatto per un numero maggiore di confronti quando possibile.

    Ad esempio, immagina di voler abbinare la rappresentazione numerica di ogni mese (da 1 a 12) con il nome del mese. Con una struttura if - else if, dovresti fare dodici confronti simili. Ma con switch, puoi farlo in modo molto più ordinato senza ripetere il codice.

    Per esercitarti nell'uso della sintassi del condizionale switch con questo esempio sui mesi, aggiungi le seguenti righe a jshell. C'è una variabile int che rappresenta numericamente il mese dell'anno e un case per il nome di ciascun mese:

    1. int monthOfYear = 1;
    2. switch (monthOfYear) {
    3. case 1:
    4. System.out.println("January");
    5. break;
    6. case 2:
    7. System.out.println("February");
    8. break;
    9. default:
    10. System.out.println("Not a month");
    11. }

    Alla riga 1, c'è una variabile monthOfYear con il valore 1. Questa variabile verrà utilizzata per l'istruzione switch. Alla riga 2 c'è la definizione dell'istruzione switch. La variabile monthOfYear viene inserita tra parentesi per indicare che verrà confrontata. Dopodiché inizia il blocco di codice all'interno del quale sono descritti i diversi condizionali case.

    Alla riga 3 arriva il primo caso con valore 1. Il primo confronto sarà se monthOfYear è uguale a 1. I due punti (:) seguono sempre il valore confrontato. Alla riga 4 arriva il metodo println() per stampare che nel caso in cui 1 viene trovato, dovrebbe stampare Gennaio come nome del mese. Questa riga potrebbe contenere zero o più istruzioni su zero o più righe, ovvero potrebbe essere saltata.

    Dopo il primo caso arriva un'istruzione break alla riga 5, che provoca l'uscita dalla struttura condizionale switch quando la condizione è soddisfatta. Pertanto, una volta eseguito break, nessun altro condizionale case verrà valutato. Invece, il flusso del programma continuerà dopo la parentesi di chiusura del condizionale switch, che si trova alla riga 11 in questo esempio. Nota che break è facoltativo e potresti dimenticarti di includerlo. In tal caso, lo switch continuerà a valutare i casi rimanenti invece di interrompere la struttura condizionale quando c'è una corrispondenza. Ciò può portare a output imprevisti e problemi difficili da eseguire il debug.

    Il successivo condizionale case è alle righe 6, 7 e 8, che corrisponderà se il valore monthOfYear è 2. Queste tre righe seguono la stessa sintassi delle tre precedenti ma con una nuova stringa per February nella riga 7. Per brevità, i condizionali case per i restanti dieci mesi hanno stato omesso. Altrimenti, seguirebbero anche questa struttura con nuove stringhe per ogni mese indicato.

    Alla riga 9 c'è un'istruzione default. Non ha condizioni e quindi è sempre abbinato. È facoltativo e viene utilizzato per definire il percorso predefinito per il flusso del programma quando non viene trovato alcun caso elencato in precedenza. È simile all'istruzione else nei condizionali if.

    Alla riga 11 c'è la parentesi di chiusura per terminare il blocco di codice per le istruzioni condizionali.

    Per eseguire il codice sopra, incollalo in jshell. Riceverai il seguente output:

    Output
    monthOfYear ==> 1 January

    La prima riga conferma che il valore di monthOfYear è 1. La seconda riga stampa gennaio, il che significa che il condizionale case per il valore 1 è stato abbinato: il monthOfYear è 1, che attiva l'istruzione nella riga successiva per stampare gennaio.

    Come esercizio, prova a cambiare il valore di monthOfYear, aggiungendo altri condizionali case e persino rimuovendo le istruzioni break per capire come cambierà il risultato .

    Conclusione

    In questo tutorial, hai utilizzato istruzioni condizionali per dirigere il flusso di esecuzione. Hai imparato quando è opportuno usare le istruzioni if e switch e hai scritto alcuni esempi di codice con esse. Hai anche appreso le migliori pratiche per il codice pulito e come evitare le insidie comuni relative ai condizionali.

    Per ulteriori informazioni su Java, consulta la nostra serie How To Code in Java.