:: Enseignements :: ESIPE :: E4INFO :: 2018-2019 :: Java Inside ::
[LOGO]

Switch


Switch, Fallthrough, Representation en bytecode

Exercice 1 - Switch in Java

Le but de cet exercice est se familiariser avec la façon dont les switchs sont compilés en Java.

  1. Créer un répertoire lab02 dans le repository java-inside
    Ajouter la version de pro "early-access" à votre PATH
          export PATH=$PATH:/home/ens/forax/java-inside/pro-jdk-12
        

    Exécuter pro scaffold dans le répertoire lab02 pour obtenir les fichiers de départ. Puis créer un projet Eclipse pointant sur le répertoire lab02 et faite en sorte que le JDK utiliser pour ce projet (dans Property > Build Path) pointe sur Pro.
  2. Dans Eclipse, créer une classe Switches ainsi qu'une méthode publique intSwitch qui prend en paramètre un entier et renvoie une String "zero" si l'entier est 0, "one" si l'entier est 1 et "a lot" si l'entier est 2.
    Ecrire un test unitaire SwitchesTests qui test avec les valeurs -1, 0, 1 et 2.
  3. Modifier le fichier .travis.yml pour que l'orsque vous fassiez un commit, le lab02 soit tester avec la bonne version de Pro.
    Utiliser pour cela la build matrix pour que Travis test chaque lab (pour l'instant le lab01 et le lab02) en parallèle.
  4. Utiliser javap (pro/bin/javap -verbose -private ... pour afficher le bytecode correspondant.
    A quel bytecode correspond un switch et à quoi corresponde les valeurs à coté ?
  5. Copier-coller la méthode intSwitch dans une méthode intSwitch2 qui marche comme intSwitch mais avec les valeurs 0, 10 et 100.
    Regarder le bytecode générer et comparer la façon dont les switchs sont générer. Pourquoi ?
  6. Modifier le test unitaire pour que le même code test aussi bien intSwitch que intSwitch2 en utilisant un ParameterizedTest et l'annotation @MethodSource.
    Note: vous devez ajouter au fichier de build.pro la dépendance sur org.junit.jupiter.params qui se trouve sur Maven Central avec les coordonnées d'artifact org.junit.jupiter:org.junit.jupiter-params:5.3.1.
    Indication: vous avez besoin d'une interface fonctionnelle et d'un tableau !
  7. Ajouter dans intSwitch et intSwitch2 un cas pour la valeur 3 qui fait la même chose que le cas 0 (avec un fallthrough). Puis regarder dans bytecode généré.
    Penser aussi à modifier le test unitaire pour tester le nouveau cas !
  8. Il existe deux formes de fallthrough en Java (comme en C en fait), le cas où deux cases sont successifs et le cas ou il y a une instruction entre deux cases successifs.
         switch(i) {                         switch(i) {
           case 0:                             case 0:       
           case 1:                               ...instructions1
             ... instructions                  case 1:
         }                                       ...instructions2
                                             }
       

    Expliquer pourquoi les developpers n'aime pas les fallthrough et quelles formes est la pire.
  9. Ajouter une nouvelle méthode stringSwitch qui au lieu d'utiliser les valeurs 0, 1, 2 et 3 utilise les valeurs "foo", "bar", "baz" et "viva zorg" à la place (les valeurs de retour doivent être les mêmes.
    Modifier le test unitaire pour qu'il marche aussi avec la méthode stringSwitch avec les bonnes chaines de caractères. Pourquoi il faut aussi ajouter un nouveau test unitaire spécifique à stringSwitch ?
    Comparer le bytecode généré avec les deux versions précédentes. D'où vienne les valeurs ?
  10. Ajouter une nouvelle méthode enumSwitch qui au lieu d'utiliser les valeurs 0, 1, 2 et 3 utilise les valeurs DEBUG, WARNING, INFO, ERROR à la place.
    Modifier encore une fois les tests unitaires en conséquence.
    Comparer le bytecode généré avec les trois versions précédentes. D'où vienne les valeurs ?
  11. Que peut-on en déduire en terme de compatibilité si on ajoute des valeurs dans un enum ?