W3docs

L'instruction switch en Java

Utilisez l'instruction switch en Java pour brancher sur des valeurs, avec des étiquettes case, break, default et le comportement de fall-through.

Lorsque vous devez comparer une seule valeur contre de nombreuses possibilités, une longue chaîne if/else if devient rapidement bruyante. L'instruction switch est l'alternative compacte de Java — lire la valeur une seule fois, sauter au case correspondant, exécuter son bloc.

Syntaxe de base

switch (value) {
  case label1:
    // body
    break;
  case label2:
    // body
    break;
  default:
    // body
    break;
}

Un petit exemple :

int day = 3;

switch (day) {
  case 1:
    System.out.println("Monday");
    break;
  case 2:
    System.out.println("Tuesday");
    break;
  case 3:
    System.out.println("Wednesday");
    break;
  default:
    System.out.println("Other");
    break;
}

Le switch saute à case 3:, affiche Wednesday, rencontre break et sort.

Le break est essentiel

Sans break, l'exécution tombe dans le cas suivant — même si son étiquette ne correspond pas. C'est une fonctionnalité délibérée du switch de style C, mais c'est la source d'innombrables bugs dans le code Java :

switch (day) {
  case 1:
    System.out.println("Monday");
    // no break!
  case 2:
    System.out.println("Tuesday");
    break;
}

Quand day == 1, cela affiche à la fois Monday et Tuesday. Ajoutez toujours break sauf si vous souhaitez intentionnellement un fall-through.

Fall-through intentionnel

Parfois le fall-through est exactement ce que vous voulez — regrouper plusieurs étiquettes sous le même bloc :

switch (day) {
  case 1:
  case 2:
  case 3:
  case 4:
  case 5:
    System.out.println("Weekday");
    break;
  case 6:
  case 7:
    System.out.println("Weekend");
    break;
}

Lorsque vous faites cela intentionnellement, ajoutez un commentaire // fall through pour que les relecteurs ne pensent pas que vous avez oublié un break. (La nouvelle syntaxe d'expression switch — couverte dans le chapitre suivant — corrige entièrement ce piège.)

Quelles valeurs peut accepter un switch ?

Un switch traditionnel accepte :

  • Tous les types entiers : byte, short, int, char
  • Leurs wrappers boxés : Byte, Short, Integer, Character
  • String (depuis Java 7)
  • Les constantes enum

Non autorisés : long, float, double, boolean, ou des objets arbitraires. Pour ceux-là, utilisez if/else.

String role = "admin";

switch (role) {
  case "admin":
    System.out.println("Full access");
    break;
  case "editor":
    System.out.println("Write access");
    break;
  case "viewer":
    System.out.println("Read access");
    break;
  default:
    System.out.println("No access");
    break;
}

La comparaison de chaînes dans un switch utilise la sémantique String.equals — sensible à la casse. Un point délicat : effectuer un switch sur un String (ou toute valeur boxée/enum) qui est null lève une NullPointerException. Vérifiez la valeur null avant le switch, ou gérez-la dans un garde :

if (role == null) {
  System.out.println("No role");
} else {
  switch (role) {
    case "admin":
      System.out.println("Full access");
      break;
    // ...
  }
}

default — le cas attrape-tout

default s'exécute quand aucun case ne correspond. Ce n'est pas obligatoire, mais l'inclure est une bonne pratique ; cela rend explicite le comportement pour les valeurs inattendues.

default n'a pas besoin d'être en dernier. Par convention il se place en bas, mais le compilateur l'accepte n'importe où — l'exécution tombe dedans comme pour tout autre case si vous oubliez un break.

Règles à garder en tête

Quelques règles imposées par le compilateur piègent souvent les développeurs :

  • Les étiquettes de case doivent être des constantes de compilation. Vous pouvez utiliser des littéraux (case 3:), des constantes final, ou des noms d'enum — mais pas une variable ni un appel de méthode. case x:x est une variable non-finale ne compilera pas.
  • Les étiquettes doivent être uniques. Deux entrées case 3: dans le même switch sont une erreur de compilation.
  • Tous les cases partagent la même portée. Une variable déclarée dans un case est visible dans les autres, ce qui peut créer des conflits. Enveloppez le corps d'un case dans des accolades { } lorsque vous avez besoin d'une variable locale limitée à ce case :
switch (day) {
  case 1: {
    int hours = 8;
    System.out.println(hours);
    break;
  }
  case 2:
    // `hours` is not visible here
    break;
}

Utiliser switch avec enum

enum et switch forment une paire naturelle. Dans un switch sur une valeur d'enum, vous n'avez pas besoin de qualifier le nom de la constante :

enum Status { PENDING, ACTIVE, DONE }

Status s = Status.ACTIVE;

switch (s) {
  case PENDING:           // not Status.PENDING
    System.out.println("Waiting...");
    break;
  case ACTIVE:
    System.out.println("In progress");
    break;
  case DONE:
    System.out.println("Finished");
    break;
}

Un exemple pratique

java— editable, runs on the server

Et ensuite

Java 14 a introduit les expressions switch, qui retournent une valeur, éliminent le fall-through et prennent en charge les cases à étiquettes multiples — le code Java moderne les préfère dès lors que vous ciblez Java 14 ou plus récent.

Pratique

Pratique
Dans un switch Java traditionnel, que se passe-t-il si vous omettez break dans un bloc case ?
Dans un switch Java traditionnel, que se passe-t-il si vous omettez break dans un bloc case ?
Was this page helpful?