Participer au site avec un Tip
Rechercher
 

Améliorations / Corrections

Vous avez des améliorations (ou des corrections) à proposer pour ce document : je vous remerçie par avance de m'en faire part, cela m'aide à améliorer le site.

Emplacement :

Description des améliorations :

Les instructions conditionnelles

Définition de blocs d'instructions Le nouveau switch de Java SE 14



Accès rapide :
La vidéo
L'instruction if / else
Aspects syntaxiques
Utiliser les templates de génération de code proposés par Eclipse
Comparatif avec les langages C/C++
Travaux pratiques
L'instruction switch / case
Limitation d'utilisation de l'instruction switch / case
Aspects syntaxiques
Le switch/case, une instruction optimisée
Cas des chaînes de caractères
Travaux pratiques
L'expression conditionnelle
Travaux pratiques

La vidéo

Cette vidéo vous montre comment utiliser les instructions conditionnelles en Java (if/else et switch/case). Une comparaison entre les deux mécanismes est proposée. L'opérateur conditionnel est aussi présenté (le seul opérateur ternaire du langage).


Les instructions conditionnelles

L'instruction if / else

Aspects syntaxiques

L'instruction if est une instruction conditionnelle : elle exécute des portions de code en fonction en fonction qu'une condition soit vraie ou fausse (la condition doit calculer une valeur booléenne). Dans beaucoup de langages de programmation (Visual Basic, Pascal, ...) l'instruction if est aussi associée au mot clé then : ce n'est pas le cas en Java. Effectivement, comme nous l'avons dit à maintes reprises, Java s'inspire de la syntaxe du langage C dont il en reprend bon nombre d'aspects. C'est donc aussi le cas pour le if et en C le mot clé then n'existe pas ! La condition doit être globalement parenthésée, ce qui retire l'obligation d'avoir un autre mot clé pour débuter le bloc de code dans le cas où la condition est vraie. En voici un exemple.

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
 13 
 14 
public class Demo {

    public static void main( String [] args ) {
    
        // La condition est globalement parenthésée
        if ( args.length == 0 ) {
            System.out.println( "Usage: java Demo files..." );
            return;    
        }   
         
        // Suite du code
    }
            
}
La condition doit être parenthésée

Si vous oubliez les parenthèses autour de la condition, une erreur de compilation sera produite. Voici un exemple de code produisant cette erreur.

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
 13 
 14 
public class Demo {

    public static void main( String [] args ) {
    
        // Attention, cela ne compile pas. Voir le message d'erreur ci-après
        if args.length == 0 {
            System.out.println( "Usage: java Demo files..." );
            return;    
        }   
         
        // Suite du code
    }
            
}
La condition doit être parenthésée et là, ce n'est pas bon !!!

Et voici le message d'erreur produit.

$> javac Demo.java
Demo.java:6: error: '(' expected
        if args.length == 0 {
          ^
Demo.java:6: error: ')' expected
        if args.length == 0 {
                           ^
2 errors
$> 

Par contre, les accolades autour du code à exécuter, dans le cas où la condition est vraie, sont facultatives. Mais attention, dans ce cas, seule une unique instruction pourra être exécutée. Regardez, dans l'exemple ci-dessous, les accolades ont étaient retirées et deux affichages sont proposés. Il est vrai qu'un retrait (une indentation) vers la droite précède les deux affichages. Malgré cela, le second affichage sera exécuté quelques soit le résultat calculé par la condition. En fait il suit la condition et aurait dû être placé au même niveau que le if.

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
public class Demo {

    public static void main( String [] args ) {
    
        if ( args.length == 0 )
            System.out.println( "Usage: java Demo files..." );
            System.out.println( "Autre affichage" );

        /* Ce code aurait du être indenté ainsi, pour une meilleure compréhension
        if ( args.length == 0 )
            System.out.println( "Usage: java Demo files..." );
        System.out.println( "Autre affichage" );
        */
         
        // Suite du code
    }
            
}
Attention à vos accolades si vous souhaitez exécuter plusieurs instructions.

Et voici les résultats produits suite à deux exécutions différentes de votre code.

$> javac Demo.java 
$> java Demo 
Usage: java Demo files...
Autre affichage
$> java Demo file1 file2
Autre affichage
$>

Un autre mot clé est utile au if : le mot clé else. Il permet de lancer l'exécution d'un code dans le cas où la condition renvoie l'état false. De même que pour la partie de code à exécuter dans le cas où la condition calcule true, les accolades peuvent être mises ou non.

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
 13 
 14 
public class Demo {

    public static void main( String [] args ) {
    
        if ( args.length == 0 )
            System.out.println( "Usage: java Demo files..." );
            return;
        } else {
            // Traitement des fichiers
        }
        
    }
            
}
Un if avec une branche else
personnellement, je vous conseille vivement de mettre les accolades dans les deux cas (if / else). Cela ne laisse aucune ambiguïté sur ce qui doit être exécuté ou non. De plus, si vous utilisez l'assistant Eclipse pour produire vos if, il générera systématiquement les accolages : c'est très bien. Pour rappel, tapez if suivant le la séquence de touches CTRL + Espace, pour activer l'assistant de génération de code.

Enfin, du point de vue de la syntaxe, notez qu'il n'existe pas de mot clé elif ou elsif en Java. Pour autant, il est possible d'imbriquer plusieurs if en cascade. L'exemple suivant transforme les valeurs numériques comprises entre 0 et 9 en leurs équivalents textuels.

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
 19 
 20 
 21 
 22 
 23 
 24 
 25 
 26 
 27 
 28 
 29 
 30 
 31 
public class Demo {

    public static void main( String [] args ) {
    
        int value = (int) (Math.random() * 10);
        
        if ( value == 0 ) {
            System.out.println( "Zéro" );
        } else if ( value == 1 ) {
            System.out.println( "Un" );
        } else if ( value == 2 ) {
            System.out.println( "Deux" );
        } else if ( value == 3 ) {
            System.out.println( "Trois" );
        } else if ( value == 4 ) {
            System.out.println( "Quatre" );
        } else if ( value == 5 ) {
            System.out.println( "Cinq" );
        } else if ( value == 6 ) {
            System.out.println( "Six" );
        } else if ( value == 7 ) {
            System.out.println( "Sept" );
        } else if ( value == 8 ) {
            System.out.println( "Huit" );
        } else {
            System.out.println( "Neuf" );
        }
        
    }
            
}
Exemple de if imbriqués
c'est vrai que dans ce cas on fait une exception, quand à l'utilisation de accolades, sur les blocs else qui relance une condition. Si on n'avait pas fait cela, les if imbriqués auraient de plus en plus été décalés vers la droite.

Utiliser les templates de génération de code proposés par Eclipse

Nous en avons déjà un peu parlé, vous avez la possibilité de générer un bloc if, voir if/else via l'atelier Eclipse. J'aimerais revenir quelques instants sur cette possibilité, car vous pouvez compléter ces possiblités.

Donc Eclipse, mais aussi certains autres IDE (Integrated development environment), fournit le concept de template (à ne pas confondre avec les templates C++). Un template est un modèle de code qui est enregistré dans l'IDE. Ce modèle de code est associé à un nom et il sera possible, durant l'édition de vos codes, d'utiliser ce nom pour y injecter la séquence de code associée. Pour réaliser cette injection, il faut taper le nom du template puis appuyer simultanément sur les touches CTRL + Espace : normalement, le nom du modèle (du template) doit être remplacé par le code Java équivalent.

Pour obtenir la boîte de dialogue de configuration des templates, ouvrez le menu « Window », puis activer l'élément de menu « Preferences ». La boîte de dialogue d'édition des préférences s'ouvre : dans l'arborescence (dans la partie gauche), sélectionnez le noeud « Java / Editor / Templates ». Vous pourrez y voir les templates déjà existant (syserr, sysout, main, if, ifelse, ...). La capture d'écran ci-dessous vous montre les deux définitions de templates relatives à l'instruction if.


Les templates de code de l'IDE Eclipse

Pour modifier le code d'un modèle existant, veuillez cliquer sur le bouton « Edit... » situé à droite de la boîte de dialogue. Pour en ajouter un nouveau, veuillez cliquer sur le bouton « New... ». Notez aussi qu'un modèle ne contient pas que du texte brut. Effectivement, dans la capture d'écran proposée, vous pouvez apercevoir deux variables dans le modèle et notamment la variable ${cursor}. Cette variable permet de préciser l'emplacement du curseur dans l'éditeur, une fois le modèle injecté : c'est très pratique. Il existe de nombreuses autres variables utilisables dans un modèle de code Eclipse.

Comparatif avec les langages C/C++

si vous êtes déjà programmeur C ou C++, faites bien attention à un point de détails qui pourrait vous poser problème. En C (et donc en C++) il n'y a pas de type booléen à proprement parlé. En fait, un booléen est un entier. Si une variable vaut 0, on assimile cette valeur à l'état faux. Toutes les autres valeurs représentent l'état vrai. Il est donc courant de voir en C une instruction if dont la condition de test calcule une donnée entière. Cela ne marche pas en Java.

Le contrôle de typage du compilateur Java est plus strict que celui de C. En Java, la condition du if doit obligatoirement calculer une valeur booléenne. Dans tout autre cas, une erreur de compilation sera générée.

Travaux pratiques

Le sujet

L'objectif de ce TP est de produire un code permettant de déterminer si une année (saisie par l'utilisateur) est bissextile ou non. La difficulté réside dans l'algorithme à utiliser pour savoir si l'on a à faire à une année bissextile : voici cet algorithme.


Pour permettre la saisie d'une valeur entière, je vous propose le code suivant. Nous reviendrons ultérieurement sur ce Scanner et la construction try (ici c'est plus précisément un « try-with-resources »), pour l'heure acceptez simplement que la méthode nextInt vous renvoie l'entier saisie sur la console.

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
import java.util.Scanner;
            
public class Demo {

    public static void main( String [] args ) {
    
        try ( Scanner scanner = new Scanner( System.in ) ) {
        
            System.out.print( "Veuillez saisir une année : " );
            int year = scanner.nextInt();
        
            // TODO: continuer le TP
        
        }
    
    }

}
Exemple de code permettant la saisie d'un entier sur la console.

Pour rappel, pour savoir si un entier est multiple d'une valeur, vous pouvez utiliser l'opérateur % (le modulo, ou encore le reste de la division entière). Par exemple 10 % 5 calcule 0 car 10 est divisible par 5 et que le reste de cette division entière est 0. Voila, c'est maintenant à vous de me proposer une solution à ce problème. Jouez le jeu et ne passez pas directement à la correction ;-)

La correction

Je vous propose une première version ou nous allons simplement traduire l'énoncé en code Java.

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
 19 
 20 
 21 
 22 
 23 
 24 
 25 
 26 
 27 
 28 
 29 
 30 
 31 
 32 
 33 
 34 
 35 
import java.util.Scanner;
            
public class Demo {

    public static void main( String [] args ) {
    
        try ( Scanner scanner = new Scanner( System.in ) ) {
        
            System.out.print( "Veuillez saisir une année : " );
            int year = scanner.nextInt();
        
            boolean isBissextile;
            
            if ( year % 4 != 0 ) {
                isBissextile = false;           // year n'est pas un multiple de 4
            } else {
                if ( year % 400 == 0 ) {
                    isBissextile = true;        // year est multiple de 400
                } else if ( year % 100 == 0 ) {
                    isBissextile = false;       // year est multiple de 100, mais pas de 400 (else)
                } else {
                    isBissextile = true;
                }
            }
        
            if ( isBissextile ) {
                System.out.printf( "L'année %d est bissextile\n", year );
            } else {
                System.out.printf( "L'année %d n'est pas bissextile\n", year );
            }
        }
    
    }

}
Calculs d'années bissextiles.

Maintenant, notez qu'on aurait pu compacter les tests en utilisant les opérateurs && (et logique) et || (ou logique) : cela permet de ne pas trop répéter les if. Notez aussi que 400 et 100 sont des entiers multiples de 4. On peut donc réécrire le programme ainsi :

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
 19 
 20 
 21 
 22 
import java.util.Scanner;
            
public class Demo {

    public static void main( String [] args ) {
    
        try ( Scanner scanner = new Scanner( System.in ) ) {
        
            System.out.print( "Veuillez saisir une année : " );
            int year = scanner.nextInt();
        
            if ( year % 400 == 0 || (year % 4 == 0 && year % 100 != 0) ) {
                System.out.printf( "L'année %d est bissextile\n", year );
            } else {
                System.out.printf( "L'année %d n'est pas bissextile\n", year );
            }
                        
        }
    
    }

}
Calculs d'années bissextiles.

L'instruction switch / case

Tout comme l'instruction if, le switch permet de déclencher des traitements en fonction des valeurs d'une expression. D'un certain point de vue, cette instruction est similaire à plusieurs if imbriqués. Néanmoins, il y a des différences notables entre les deux instructions :

Limitation d'utilisation de l'instruction switch / case

Comme nous venons de le dire, un switch ne peut pas travailler sur des valeurs flottantes. Si vous tentez malgré tout de compiler un tel programme, une erreur de compilation sera produite. Voici un exemple basé sur des valeurs de type double.

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
public class Demo {

    public static void main( String [] args ) {
                        
        double value = Math.random() * 10;
        switch ( value ) {
            case 1.0:
                System.out.println( "Ne peut pas compiler" );
                break;
            default:
                System.out.println( "Autre valeur" );
        }
        
    }

}
Tentative d'utilisation d'un switch sur double

Et voici le message d'erreur produit lors d'une tentative de compilation.

$> javac Demo.java
Demo.java:6: error: incompatible types: possible lossy conversion from double to int
        switch ( value ) {
               ^
1 error
$> 

Aspects syntaxiques

Regardons maintenant un exemple de code qui compile parfaitement : il s'agit d'un programme équivalent à celui vu précédemment avec l'instruction if pour afficher en toutes lettres un chiffre compris entre 0 et 9.

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
 19 
 20 
 21 
 22 
 23 
 24 
 25 
 26 
 27 
 28 
 29 
 30 
 31 
 32 
 33 
 34 
 35 
 36 
 37 
 38 
 39 
 40 
 41 
 42 
 43 
 44 
public class Demo {

    public static void main( String [] args ) {
                        
        int value = (int) (Math.random() * 11);

        switch( value ) {
            case 0:
                System.out.println( "Zéro" );
                break;
            case 1:
                System.out.println( "Un" );
                break;
            case 2:
                System.out.println( "Deux" );
                break;
            case 3:
                System.out.println( "Trois" );
                break;
            case 4:
                System.out.println( "Quatre" );
                break;
            case 5:
                System.out.println( "Cinq" );
                break;
            case 6:
                System.out.println( "Six" );
                break;
            case 7:
                System.out.println( "Sept" );
                break;
            case 8:
                System.out.println( "Huit" );
                break;
            case 9:
                System.out.println( "Neuf" );
                break;
            default:
                System.out.println( "Ce n'est plus un chiffre, mais un nombre" );
        }
        
    }

}
Exemple d'utilisation d'un switch sur entier

Comme vous l'aurez constaté, chaque case est associé à une valeur à tester et il se termine par une instruction break. Cette dernière instruction est très importante dans notre cas : elle permet que l'exécution ne se poursuive pas au case suivant. Effectivement, l'instruction switch/case est prévue pour définir des intervalles de valeurs, comme le montre l'exemple ci-dessous.

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
 19 
 20 
 21 
 22 
 23 
 24 
 25 
 26 
 27 
 28 
public class Demo {

    public static void main( String [] args ) {
                        
        int value = (int) (Math.random() * 11);

        switch( value ) {
            case 0:
            case 1:
            case 2:
            case 3:
            case 4:
                System.out.println( "Petit chiffre" );
                break;
            case 5:
            case 6:
            case 7:
            case 8:
            case 9:
                System.out.println( "Grand chiffre" );
                break;
            default:
                System.out.println( "Ce n'est plus un chiffre, mais un nombre" );
        }
        
    }

}
Exemple d'utilisation d'un switch sur entier

Cet exemple définit trois cas possibles d'exécution :

N'oubliez donc pas vos break si vous ne souhaitez pas poursuivre l'exécution du code au bloc suivant.

Petit complément d'information pour les utilisateurs de l'IDE Eclipse (et de quelques autres IDE) : tout comme pour l'instruction if, il existe un template permettant de générer un squelette d'instruction switch. Pour obtenir cette possibilité, commencez à tapez le mot switch à l'endroit souhaité puis, encore une fois, appuyez simultanément sur CTRL et ESPACE : vous devriez pouvoir activer le template et générer la séquence de code souhaitée.

Le switch/case, une instruction optimisée

Organisation du code du switch en mémoire

Comme nous l'avons dit en introduction, comparé à un l'instruction if, l'instruction switch est optimisée. Dans les exemples de transformation d'une valeur numérique entière en son équivalent textuel, un if peut réaliser un grand nombre de tests avant de trouver le bon bloc à exécuter. Au contraire un switch trouveras le bon bloc en temps constant et ce quelle que soit la valeur numérique entière considérée.

Pour effectuer ce tour de force, le compilateur Java pré-calcule un tableau contenant les adresses mémoire des codes à exécuter pour chaque valeur possible. Ainsi, durant l'exécution, il suffira de retrouver l'entrée du tableau correspond à la valeur considérée (déterminée en temps constant) puis de sauter à l'adresse mémoire stockée dans cette entrée. Considérons l'exemple de code ci-dessous : l'image, proposée sur votre droite, montre comment les choses seront organisées en mémoire.

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
 13 
switch( index ) {
    case 0:
        // code branche 0;
        break;
    case 1:
        // code branche 1;
        break;
    case 3:
        // code branche 3;
        break;
    default:
        // code branche default;
}
Exemple d'un switch avec des trous dans l'intervalle des valeurs testées

Si vous regardez bien l'exemple de code, vous noterez qu'il n'y a pas de case pour la valeur 2. Pour autant le tableau de pointeurs possède bien une entrée pour cette valeur et le pointeur considéré renvoie sur le bloc default. Pour les valeurs en dehors des bornes, deux tests préalables sont réalisés et si on est bien en dehors des bornes du tableau, on renvoie aussi sur default.

Imaginons un autre cas : les valeurs à tester sont, par exemple, 100, 101, 102, 103, 104 et 105. Dans ce cas, le compilateur calcule la valeur minimale (soit 100) et la retire de la donnée passée en entrée du switch. Ainsi, on se retrouve bien avec un tableau de pointeurs indicé de 0 à 5 : l'optimisation est bien mise en oeuvre.

en regardant l'image proposée, on comprend mieux pourquoi si l'on oublie le break dans une branche, alors l'exécution se poursuit au bloc suivant. Les blocs s'enchaînent en mémoire dans le même ordre que celui qui a permis de les définir dans le code.

Enfin, il faut savoir que cette optimisation ne peut pas être utilisée pour des switch sur chaînes de caractères ou sur des types énumérés. Pour autant d'autres optimisations, adaptées à ces types, sont mises en oeuvre.

Cas des chaînes de caractères

Comme l'on vient de le préciser, on peut appliquer un switch sur des chaînes de caractères. Il faut néanmoins noter que l'on peut utiliser cette possibilité que depuis la version Java SE 7.0. Avant, une erreur de compilation était produite. Si vous êtes dans ce cas, préférez l'utilisation de if imbriqués.

Voici un exemple d'utilisation d'un switch sur des chaînes de caractères : il permet de simuler un petit interpréteur de commandes. Tapez exit pour sortir de ce mini-shell.

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
 19 
 20 
 21 
 22 
 23 
 24 
 25 
 26 
 27 
 28 
 29 
 30 
 31 
 32 
import java.util.Scanner;

public class Demo {

    public static void main( String [] args ) throws Exception {

        try ( Scanner scanner = new Scanner( System.in ) ) {

            while( true ) {
                System.out.print( "Enter a command: ");
                String command = scanner.nextLine().trim();
                
                switch( command ) {
                    case "exit":
                        System.out.println( "Bye bye" );
                        return;
                    case "command1":
                        System.out.println( "Imagine a command for your system" );
                        break;
                    case "command2":
                        System.out.println( "Imagine another command for your system" );
                        break;
                    default:
                        System.out.println( "Command not found. Please retry!" );
                }
            }

        }

    }
            
}
Utilisation d'un switch avec des chaînes de caractères
l'instruction try nous permet, dans ce cas d'utilisation, fermer automatiquement l'instance scanner (via un appel de la méthode close) en sortie du programme. La sortie du programme s'obtient lors de l'exécution du return dans le bloc case "exit". Nous reviendrons ultérieurement sur le fonctionnement de cette instruction. De même, nous reviendrons ultérieurement sur l'utilisation du mot clé throws (à la fin du main).

Travaux pratiques

Le sujet

Le but de ce TP est d'écrire un programme permettant d'appliquer une opération sur deux valeurs numériques. L'opérateur ainsi que les valeurs doivent être saisis à partir de la console en suivant le format suivant : java Demo operator value1 value2. Un minimum de quatre opérateurs doivent être fournis : add, sub, mul et div. Voici un petit exemple d'utilisation du programme à développer.

$> java Demo
Usage: java Demo operator value1 value2
$> java Demo add 10.2 3.4
13.6
$> java Demo sub 10.2 3.4
6.8
$> java Demo mul 5 3
15.0
$> java Demo div 10 5
2.0
$>

Voila, c'est maintenant à vous de me proposer une solution à ce problème. Jouez le jeu et ne passez pas directement à la correction ;-)

La correction

Pour choisir l'opération à exécuter en fonction de l'opérateur renseigné, je vous conseille d'utiliser l'instruction switch afin d'avoir un programme plus lisible et efficace. Voici ma correction.

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
 19 
 20 
 21 
 22 
 23 
 24 
 25 
 26 
 27 
 28 
 29 
 30 
 31 
 32 
 33 
public class Demo {

    public static void main( String [] args ) {

        if ( args.length != 3 ) {
            System.out.println( "Usage: java Demo operator value1 value2" );
            System.exit( 0 );
        }

        String operatorName = args[0];
        double value1 = Double.parseDouble( args[1] );
        double value2 = Double.parseDouble( args[2] );

        switch( operatorName ) {
            case "add":
                System.out.println( value1 + value2 );
                break;
            case "sub":
                System.out.println( value1 - value2 );
                break;
            case "mul":
                System.out.println( value1 * value2 );
                break;
            case "div":
                System.out.println( value1 / value2 );
                break;
            default:
                System.out.println( "Undefined operator " + operatorName );
        }

    }

}
Un évaluateur d'expressions développé grâce au switch.

L'expression conditionnelle

Quand à parler d'exécutions conditionnelles, je souhaitais aussi présenter l'opérateur conditionnel. Certes, ce n'es pas une instruction, mais bien un opérateur (qui calcule une valeur), mais son fonctionnement est assez proche d'un if/else. Le format d'utilisation de cet opérateur est le suivant :

booleanExpression ? trueExpression : falseExpression
l'opérateur conditionnel est le seul opérateur ternaire du langage Java. Cela veut dire que c'est le seul opérateur Java à accepter trois opérandes.

Donc, pour utiliser l'opérateur conditionnel, il faut fournir trois opérandes. Le premier correspond à l'expression de test : cette expression doit renvoyer une valeur booléenne. Le second opérande, séparé du premier par un caractère ?, correspond à la valeur à calculer dans le cas où l'expression initiale est vraie. Le troisième opérande, séparé du second par le caractère :, correspond à la valeur à calculer dans le cas où l'expression initiale est fausse. Voici un petit exemple d'utilisation.

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
 19 
import java.util.Scanner;

public class Demo {

    public static void main( String [] args ) {

        try ( Scanner scanner = new Scanner( System.in ) ) {

            System.out.print( "Please enter a password: " );
            String password = scanner.nextLine();

            String message = password.equals( "007" ) ? "You are connected" : "You are not connected";
            System.out.println( message ) ;

        }

    }
            
}
Exemple d'utilisation de l'opérateur conditionnel
il est important que les types des deux derniers opérandes soient compatibles, sans quoi une erreur de compilation sera produite. Dans l'exemple ci-dessus, on cherche à calculer une chaîne de caractères (stockée dans la variable message). Il est donc important que les deux expressions à la droite du caractère ? calculent des chaînes de caractères, ce qui est notre cas. Si vous changez l'une des deux expressions de droite afin qu'elle renvoie un entier, voici l'erreur de compilation qui sera produit.
$> javac Demo.java 
Demo.java:12: error: incompatible types: bad type in conditional expression
            String message = password.equals( "007" ) ? "You are connected" : 10;
                                                                              ^
    int cannot be converted to String
1 error
$> 

Travaux pratiques

Le sujet

Ecrire un programme qui calcul le minimum de deux valeurs qui sont passées en arguments du main, en utilisant l'opérateur conditionnel. Jouez le jeu et ne passez pas directement à la correction ;-)


La correction

A mon sens, la première des choses à faire est de transformer vos arguments en valeurs numériques : n'oubliez pas que args et un tableau de chaînes de caractères. Ensuite, comparez les deux valeurs avec l'opérateur conditionnel pour trouver le plus petit des deux.

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
public class Demo {

    public static void main( String [] args ) {

        if ( args.length != 2 ) {
            System.out.println( "Usage: java Demo value1 value2" );
            System.exit( 0 );
        }

        double value1 = Double.parseDouble( args[0] );
        double value2 = Double.parseDouble( args[1] );
        double min = value1 < value2 ? value1 : value2;

        System.out.println( "Le minimum est " + min );

    }

}
Calcul du minimum de deux arguments passés à la fonction main.


Définition de blocs d'instructions Le nouveau switch de Java SE 14