:: Enseignements :: Licence :: L3 :: 2025-2026 :: Programmation Objet avec Java ::
![[LOGO]](http://igm.univ-mlv.fr/ens/resources/mlv.png) |
Premiers pas en Java, premiers objets
|
Pour les premiers TPs, nous allons tout faire à la main sans utiliser
d'environnement de programmation, donc pas de Visual Code, d'Eclipse
ou d'IntelliJ, pour bien comprendre comment cela marche.
Nous vous conseillons d'utiliser l'éditeur de texte atom
ou SublimeText qui savent mettre le code en couleur
(et faire une complétion simple).
De plus, comme chaque exercice n'utilisera qu'une classe,
nous n'utiliserons pas les notions de privé/publique
qui interviennent que quand on a plusieurs classes qui se parlent.
Exercice 1 - Hello World
Dans un premier temps nous allons écrire des petits programmes
permettant de se familiariser avec le compilateur,
la machine virtuelle et la syntaxe du langage.
En Java, les classes
sont typiquement définies dans un fichier qui lui est propre.
Le nom du fichier doit être le nom de la classe qu'il contient,
auquel on ajoute le suffixe
.java.
Les noms des classes doivent être constitués de mots accolés
dont la première lettre est une majuscule (c'est ce qu'on appelle le
camelCase).
Écrire le programme suivant :
class HelloWorld {
static void main() {
IO.println("Hello World");
}
}
dans votre éditeur de texte et sauvegarder celui-ci
sous le nom
HelloWorld.java
On peut remarquer qu'en Java, les méthodes (sortes de fonctions) sont rangées
dans des classes, on écrit pas
println() mais
IO.println(),
car
println() est rangé dans la classe
java.lang.IO.
En on verra ce que le "static" devant le
main veut dire plus tard.
Compiler le programme en utilisant le commande
javac
puis vérifier que le fichier
.class correspondant
existe bien.
javac HelloWorld.java
Exécuter le programme avec la commande
java
java HelloWorld
On ne met pas
.class parce que la machine virtuelle le rajoute toute seule.
Déclaration d'une classe compacte.
Dans le cas où l'on a une seule classe toute seule, on peut simplifier le code
en ne déclarant pas la classe dans le fichier .java.
Simplifier le code pour voir que cela marche.
A votre avis, comment le compilateur fait pour savoir quel est le nom de la classe ?
En fait, l'intérêt des classes compactes ne résident pas dans le fait
que l'on écrit moins de lignes mais dans le fait que les imports
sont fait automatiquement.
On verra dans la suite du cours comment faire les imports à la main.
En fait, on peut exécuter avec java HelloWorld.java, sans créer le fichier
HelloWorld.class, dans ce cas, l'équivalent du fichier .class en créé en
mémoire et donc n'apparait pas sur le disque.
Supprimer le fichier "HelloWorld.clas" et vérifier que vous pouvez exécuter
directement le fichier "HelloWorld.java" avec la commande java.
Note: dans la suite des TPs, on vous demandera compiler
pour créer les fichiers ".class" car on ira occasionnellement regarder
le contenu de ces fichiers.
Exercice 2 - Arguments de la ligne de commande, boucles
Le but de cet exercice est d'écrire le main d'une classe compacte PrintArgs
qui affiche les arguments de la ligne de commande.
La classe PrintArgs s'utilisera comme suit:
$ java PrintArgs Voici des arguments
Voici
des
arguments
Les arguments de la ligne de commande sont stockés dans
le tableau de chaînes de caractères passé en argument à la méthode
static void main(String[] args).
Dans un premier temps, afficher le premier argument
de la ligne de commande (dans notre exemple Voici).
Que se passe-t-il si l'on ne passe pas d'argument lors
de l'exécution du programme ?
Écrire une boucle affichant le contenu du tableau, sachant qu'en Java, les tableaux possèdent un champ (un attribut)
length qui correspond à la taille du tableau.
Changer votre programme pour utiliser la syntaxe dite du 'for deux points', c'est à dire
for(var value: array).
Exercice 3 - Calculette simple
Le but de cet exercice est d'écrire une petite calculatrice.
Écrire une classe compacte prenant un nombre sur l'entrée standard
et affichant celui-ci.
Pour cela, on utilisera un objet
java.util.Scanner (c'est son nom complet)
qui est initialisé sur
System.in (l'entrée standard)
et la méthode
nextInt() qui renvoie l'entier correspondant à ce que tape
l'utilisateur.
static void main(String[] args) {
Scanner scanner;
scanner = new Scanner(System.in);
int value;
value = scanner.nextInt();
// compléter ici
}
}
Pour comprendre le programme, il est utile de regarder la documentation
disponible ici. Il est fortement conseillé de mettre ce lien en
bookmark.
Dans un premier temps, utiliser la
doc de Java ;
il y a une barre de recherche en haut à droite ; pour trouver la classe
java.util.Scanner,
vous pouvez aussi aller chercher
java.lang.IO que l'on a vu à l'exercice précédent.
Indiquer dans le programme où sont les variables
et quel est leur type.
Modifier le programme pour déclarer et initialiser
les variables en une seule ligne.
Dogme : À partir de maintenant, on déclarera les variables
en les initialisant et en utilisant le mot-clé var quand c'est possible.
Modifier le programme pour qu'il demande de saisir deux entiers au clavier et qu'il affiche leur somme.
Afficher en plus de la somme, la différence, le produit,
le quotient et le reste.
Exercice 4 - Record et conversion de String en entier
On souhaite écrire un programme calculant la distance entre deux points,
ou plus exactement la distance entre un point et l'origine, i.e. le point de coordonnées (0,0).
Pour cela, on va introduire un record Point qui va nous servir à représenter un point avec ses deux coordonnées.
Voici un exemple d'exécution que l'on souhaite obtenir :
$ java Point 3 4
x=3, y=4
Point[x=3, y=4]
dist = 5.0
Dans un premier temps, créer un record Point (dans
un fichier Point.java) avec deux composants x et
y, tous les deux de type int.
Quelle doit être la ligne de commande pour compiler le fichier Point.java ?
Écrire une méthode main qui déclare deux variables entières x et y,
qui leur assigne les valeurs 0, 5, puis qui crée un point p avec ces deux coordonnées.
Enfin, faire afficher le point p.
Modifier le main pour prendre en paramètre le tableau des arguments,
et utiliser les arguments pour initialiser les coordonnées x et y.
Comme les arguments de la ligne de commande sont des Strings et que l'on veut
des entiers, on va utiliser la méthode Integer.parseInt()
(n'hésitez pas à aller voir la doc).
Que se passe-t-il lorsque l'un des arguments n'est pas un nombre ?
On souhaite ajouter au record Point une méthode d'instance nommée distance
qui va prendre un autre point en paramètre et qui va calculer la distance entre ces deux points
sous forme d'un nombre à virgule flottante.
Quels sont les paramètres et le type de retour de la méthode distance ?
Écrire la méthode
distance et afficher dans le main la distance entre le point saisi par l'utilisateur
et l'origine (0, 0).
Calculer la distance entre deux points est équivalent à utiliser Pythagore sur
la distance en ordonnée et la distance en abcisse entre les deux points et qu'il existe une méthode
statique Math.sqrt (aller voir la doc !) qui renvoie la racine carrée d'un nombre.
Exercice 5 - Pour aller plus loin : C vs Java
Le but de cet exercice est de montrer que Java n'est pas forcément plus lent que C.
Cela peut paraître contre-intuitif. En effet, l'exécution d'un programme Java passe
par lancement d'une machine virtuelle qui va exécuter le bytecode produit par le compilateur Java.
De l'autre côté, le code C est transformé directement en code exécutable sur votre machine
(pas besoin de démarrer une machine virtuelle).
Le mystère est donc de savoir comment le code Java s'exécute aussi vite.
Considérons le programme suivant en C :
#include <stdio.h>
#include <stdlib.h>
int pascal (int nBut, int pBut){
int * tab;
unsigned int n, i;
tab = (int *)malloc ((nBut+1)*sizeof(int));
if(tab==NULL){
fprintf(stderr,"Pas assez de place\n");
exit(0);
}
tab[0] = 1;
for(n=1; n<=nBut; n++){
tab[n] = 1;
for(i=n-1; i>0; i--)
tab[i] = tab[i-1] + tab[i];
}
int result=tab[pBut];
free(tab);
return result;
}
int main(int argc, char * argv[]) {
printf(" Cn, p = %d\n", pascal (30000, 250));
return 0;
}
Compiler (gcc pascal.c) et exécuter le
programme a.out en demandant au système
le temps d'exécution du programme avec la commande time a.out.
Écrire le programme (Pascal.java) équivalent en Java.
Pour une fois, servez-vous du copier/coller.
Compiler le programme puis l'exécuter en mesurant le temps
(toujours avec time).
Normalement, vous devriez obtenir des temps d'exécution comparables.
Comment peut-on expliquer que le code Java soit aussi performant que le code C ?
Hint 1: Si vous voulez percer le mystère, regardez ce qu'est le JIT.
Hint 2: Si vous voulez voir qu'on vous ment un peu,
essayez de compiler le code C avec l'option -O3 qui produit un code plus optimisé
mais spécifique à la machine courante.
© Université de Marne-la-Vallée