tete du loic

 Loïc YON [KIUX]

  • Enseignant-chercheur
  • Référent Formation Continue
  • Responsable des contrats pros ingénieur
  • Référent entrepreneuriat
  • Responsable de la filière F2 ingénieur
  • Secouriste Sauveteur du Travail
mail
loic.yon@isima.fr
phone
(+33 / 0) 4 73 40 50 42
location_on
ISIMA
  • twitter
  • linkedin
  • viadeo

local_cafe Deuze local_cafe

Date de première publication : 2021/10/13

Pour ce deuxième TP, vous allez découvrir ...

Les tableaux

Comment ça marche ?

Le langage Java propose plein de structures de données compliquées mais je dois vous parler de choses avant... Alors, nous allons commencer par la structure de données la plus simple : le tableau à une dimension.

Pour déclarer une variable ou un attribut de type tableau, c'est très simple, cela se fait quasiment comme en C :


double[] array1 = null; // nécessaire si array1 est une variable
String[] array2;        // sinon cette syntaxe suffit pour un attribut

Vous l'aurez probablement compris, array1 et array2 sont des références sur des tableaux en mémoire. Les tableaux en l'état ne sont pas encore créés et les références ne sont pas valides.

Pour créer les tableaux, il y a deux possibilités :


array1 = new double[20];
array2 = new String[10];
String[] array3 = { "a", "b", "c", "d"};

array1 est un "vrai" tableaux de 20 nombres réels. On pourra accéder aux nombres en lecture et en écriture. Tous les nombres sont initialisés à une valeur par défaut.

array2 est un tableau non pas de chaînes de caractères mais de références sur des chaînes de caractère. Chaque référence a été initialisée à null.

array3 est un tableau de références vers des chaines de caractères statiques.

Un tableau en Java n'est pas redimensionnable. La taille donnée à l'instanciation est consultable par le pseudo attribut : array1.length. La classe java.lang.System propose une méthode arraycopy() pour copier les tableaux. La classe Arrays propose aussi tout un tas de méthodes intéressantes.

La machine virtuelle vérifie à l'exécution les indices de tableau. On verra plus tard comme gérer ce type d'erreur ainsi que les erreurs d'allocation mémoire.

Le langage Java supporte la syntaxe classique de la boucle for mais propose aussi la syntaxe foreach suivante :


for (String s : array2)
   System.out.println(s);

Arguments de la ligne de commande

Quand on lance un programme Java en ligne de commande, on peut taper :

$ java Exemple5 param1 "param 2" 4

Au passage, quand vous utiliserez un EDI, il vous faudra trouver comment spécifier des arguments en ligne de commande.

Quel est le paramètre d'indice 0 en C et en Java ?

Jouons...

Joueur
- liste : tableau de joueurs
+ constructeur(s)
+ afficherListe()

Vous allez maintenant réutiliser la classe Joueur du TP précédent :

Vous allez vous arranger pour stocker dans la classe Joueur, chacun des joueurs qui aura été instancié. Vous aurez probablement besoin d'un attribut pour mémoriser le nombre d'éléments du tableau effectivement présents et vous aurez besoin de figer la taille maximale du tableau, par exemple 50.

Les constructeurs devront afficher quelque chose sur la sortie d'erreur standard (cf classe System) si le tableau est plein.

La méthode afficherListe() appelle les méthodes afficher() de chacun des joueurs de la liste.

Initialisation "exotique" d'un attribut de classe

L'initialisation d'un attribut de classe peut être assez simple si elle se fait en même temps que la déclaration.


class Liste{
  static int liste = new int [50];
}

Comment peut-on faire une initialisation du tableau plus complexe ?

Il existe au moins deux possibilités, la liste peut être initialisée par une méthode de classe :


class Liste {
  static int liste = initialisation(50);

  static int[] initialisation(int taille) {
      return new int[taille];
  }
}

ou bien par un bloc statique d'instructions (en dehors de toute méthode) donc la caractéristique est d'être exécuté au moment où le fichier class est chargé en mémoire :


class Liste {
   static int liste = null;
   
   static {
      liste = new int[50];
      for(int i :liste)
         i = 3;
   }
}

Pour manipuler un caractère, vous pouver utiliser le type primitf char. Créer un attribut de classe tableau de chaines de caractères qui contienne les éléments suivant :


a
ab
abc
abcd
.....
abcdefghijklmnopqrstuvwxyz

Passage de paramètres

Dans cet exercice, vous allez déterminer comment sont passés les paramètres des méthodes. En général, on identifie le passage par valeur, par référence, par pointeur...

par l'exemple

Récupérez le code suivant Passage.java

Pour voir ce qu'il se passe, vous aller afficher avant et après un appel de méthode la valeur affectée à la variable passée en paramètre. Vous affichez aussi le paramètre en début et en fin de méthode avec par exemple :


System.out.println(objet);
System.out.println(objet.getAttribut());

Même si on verra plus tard pourquoi on peut toujours "afficher" un objet sur la sortie standard, nous devons préciser que le plus souvent cela affiche le nom de la classe, une arobase et une valeur qui s'appare à l'adresse mémoire de l'objet.

Synthese

Les paramètres en Java sont TOUJOURS passés par copie.

Organisation des classes : package ou pas package ?

L'idée de cet exercice est de montrer la structure d'un programme avec plusieurs classes, placées ou non dans des packages différents. Il faudra coder, compiler et exécuter les différents programmes à la main.

Nous allons voir TROIS manières de placer les classes / fichiers. Pour ce faire, il faudra trois répertoires principaux

Les classes à coder sont les suivantes :

Application
+ main()
Voiture
- immatriculation : chaine
+ demarrer()
+ arreter()
Camion
- immatriculation : chaine
+ demarrer()
+ arreter()

Toutes les classes dans le même fichier

On vous propose de placer les classes Application, Voiture et Camion dans un même fichier.


   public class Application {
       public static void main(String[] arg) {
           Voiture v = new Voiture();
           v.demarrer();
       }
   }

Une classe doit donner son nom au fichier, c'est la classe qui doit être déclarée public

Toutes les classes dans le même répertoire

Le compilateur Java va compiler la classe Application et toutes les classes requises par Application. Avec le code donné dans la section précédente, seules les classes Application et Voiture sont compilées.

En ce qui concerne l'exécution, seule la classe qui contient la méthode main() peut être lancée par la JVM (rien ne vous empêche d'avoir une méthode main() dans toutes les classes si vous en avez envie.

Utilisation d'un package

Nous allons maintenant utiliser un package pour ranger nos classes. La classe Application reste dans le répertoire principal et vous allez créer le package / répertoire vehicule (tout en minuscules) pour placer les classes Voiture et Camion.


.
├── Application.java
└── vehicule
    ├── Camion.java
    └── Voiture.java

Comme pour la section précédente, si les classes sont correctement nommées, le compilateur va trouver les classes comme un grand et les compiler si nécessaire.


   package vehicule;
   
   public class Voiture {
   }

En étant dans le même package, les classes Voiture et Camion se connaissent directement. En ce qui concerne la classe Application, vous pouvez utiliser l'instruction import pour simplifier le nommage


   // Choisir une des deux lignes :
   // import vehicule.*
   // import vehicule.Voiture;

   public class Application {
       public static void main(String[] arg) {
           vehicule.Voiture v = new vehicule.Voiture();
           v.demarrer();
       }
   }