Date de première publication : 2021/10/13
Pour ce deuxième TP, vous allez découvrir ...
- les tableaux en JAVA...
- le mode de passage des paramètres ...
- les packages
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 :
- soit nous demandons - comme pour un objet - l'espace mémoire nécessaire à la machine virtuelle avec le mot-clé
new
:
array1 = new double[20];
array2 = new String[10];
- soit nous énumérons les valeurs possibles à la déclaration :
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.
- Créer une classe avec une méthode de classe
main()
- Déclarer et instancier les tableaux comme ci-dessus. L'opération peut se faire en une instruction pour chacun des tableaux (déclaration+instanciation)
- Avec une boucle
for
, vérifier que les éléments ont bien été initialisés en les affichant - Que se passe-t-il si on sort des limites du tableau (indice trop petit ou trop grand) ?
- Modifier quelques élements des tableaux avec la syntaxe
[]
et réafficher les tableaux.
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.
- Affichez les paramètres un par un dans un programme sachant que la ligne de commande est passée en paramètres au point d'entrée du programme
main()
- Quelle différence notable constatez-vous avec le C ?
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
- Compilez la classe principale, cela va compiler les autres classes : vous pouvez voir des fichiers d'extension
.class
pour toutes les classes - Exécutez le programme...
Toutes les classes dans le même répertoire
- Placez les trois classes (publiques) dans trois fichiers distints. Elles sont implicitement dans le même package.
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.
- Vérifier maintenant que si
Application
référence la classeCamion
, la classe est également compilée.
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.
- Compiler et voir le message d'erreur
- Préciser que les classes
Voiture
etCamion
appartiennent au packagevehicule
tant dans les classes elle-même qu'au niveau de la classeApplication
.
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();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7