Programmer en Java

Table des matières
Introduction : un peu d'histoire
1. Java : genèse d'un nouveau langage
Programmer en Java
1. Un premier exemple
1.1. Aperçu général, cycle de vie
1.2. Un premier programme
1.3. Programmes, applets, servlets, etc...
2. Une première classe
2.1. Écriture d'une classe
2.2. Instanciation de cette classe
3. Types de base, classes et objets
3.1. Types de base
3.2. Classes et objets
Classes Object et String
1. Introduction
2. La classe Object
2.1. La méthode toString()
2.2. La méthode clone()
2.3. La méthode equals()
2.4. La méthode hashCode()
2.5. La méthode finalize()
2.6. La méthode getClass()
3. La classe String
3.1. Introduction
3.2. Construction d'un objet de type String
3.3. Concaténation, StringBuffer et StringBuilder
3.4. Concaténations de chaînes de caractères depuis Java 8
3.5. Concaténations de chaînes de caractères depuis Java 11
3.6. Extraction d'une sous-chaîne de caractères
3.7. Comparaison de deux chaînes de caractères
3.8. Méthodes de comparaisons lexicographiques
3.9. Méthode de recherche de caractères
3.10. Méthode de modification de chaîne
3.11. Méthode de duplication
3.12. Support de l'unicode, internationalisation
Structure d'une classe
1. Introduction
2. Classes
2.1. Classes publiques
2.2. Classes internes
2.3. Classe membre
2.4. Classes locales
2.5. Classes anonymes
2.6. Le mot-clé this
3. Éléments statiques
3.1. Champ statique
3.2. Cas des constantes
3.3. Bloc statique
3.4. Classe membre statique
4. Membres d'une classe, visibilité
4.1. Bloc non statique
4.2. Accès à un membre, visibilité
4.3. Les champs
4.4. Signature d'une méthode
4.5. Les méthodes
4.6. Getters et Setters
5. Constructeur, instanciation
5.1. Chargement d'une classe
5.2. Constructeurs d'une classe
5.3. Instanciation d'un objet
5.4. Destruction d'objets
5.5. Le mot-clé final
6. Énumérations
6.1. Déclaration d'une énumération
6.2. Classe énumération
6.3. Méthode toString()
6.4. Méthode valueOf()
6.5. Méthode values()
6.6. Méthode ordinal()
6.7. Méthode compareTo()
6.8. Constructeurs privés
6.9. Classe utilitaire : EnumSet
Noms, opérateurs, tableaux
1. Introduction
2. Identificateurs, noms et expressions
2.1. Identificateurs et noms
2.2. Expressions
3. Opérateurs, ordre d'exécution
3.1. Ordre d'exécution
3.2. Les opérateurs
3.3. Les opérateurs ++ et --
3.4. Les opérateurs % et /
3.5. Les opérateurs <<, >> et >>>
3.6. L'opérateur instanceof
3.7. Les opérateurs &, | et ^
3.8. Les opérateurs && et ||
3.9. L'opérateur ? ... :
3.10. Les opérateurs d'affectation
4. Tableaux
4.1. Création d'un tableau
4.2. Initialisation d'un tableau
4.3. Utilisation d'un tableau comme un Object
4.4. Tableaux de tableaux
4.5. Copie de tableaux
5. Blocs, boucles et contrôles
5.1. Blocs
5.2. Mots-clés réservés
5.3. Tests : if et switch
5.4. Boucles : for, while, do ... while
5.5. Commandes continue et break
5.6. Commandes return et goto
Nombres, précision, calculs
1. Introduction
2. Calculs
2.1. Précision
2.2. Codage des nombres flottants
2.3. Le mot-clé strictfp
2.4. Conversion de types
3. Dépassements de capacité
3.1. Cas des entiers
3.2. Cas des flottants
3.3. Bibliothèques BigInteger et BigDecimal
4. Fonctions mathématiques
4.1. Fonctions usuelles
4.2. Générateurs aléatoires
5. Classes enveloppe
5.1. Associer les types de base à des objets
5.2. Auto-boxing
Héritage, abstraction, interfaces
1. Introduction
2. Abstraction et encapsulation
2.1. Abstraction
2.2. Encapsulation
3. Héritage
3.1. Définition de l'héritage
3.2. Conséquences pour les membres
3.3. Polymorphisme
3.4. Empêcher l'héritage
4. Classes abstraites
5. Interfaces
5.1. Introduction
5.2. Définition
5.3. Java 8 et les interfaces
5.4. Utilisation des interfaces
5.5. Définition de constantes dans les interfaces
5.6. Utilité des interfaces
Packages
1. Introduction
2. Notion de paquet
2.1. Déclaration d’appartenance à un paquet
2.2. Chargement d’une classe
2.3. Choix de nom
3. Archives, chemin de recherche, classpath
3.1. Archives
3.2. Variable CLASSPATH
3.3. Notion de classloader
3.4. Bilan sur les classes chargées
3.5. Visibilité
3.6. Conseils d'écriture, bibliothèque standard
Exceptions
1. Introduction
2. Erreurs et Exceptions
2.1. Classe Throwable, notion de stack trace
2.2. Classe Error
2.3. Classe RuntimException
2.4. Classe Exception
3. Déclenchement d'une exception
3.1. Exceptions déclenchées par la JVM
3.2. Exceptions déclenchées par l'application
4. Capter une exception
4.1. Traiter une exception localement
4.2. Code de captage
5. Créer ses propres exceptions
Entrées / sorties
1. Introduction
2. Notion de fichier
2.1. Introduction
2.2. La classe File
2.3. Construction d'une instance de File
2.4. Méthodes exposées
3. Flux de sortie
3.1. Introduction, notion de flux
3.2. Écriture de caractères, classe Writer
3.3. Bufferisation, construction d'un flux sur un autre
3.4. Utilisation de PrintWriter
3.5. Écriture d'octets, OuputStream
3.6. Écriture de types primitifs : DataOutputStream
3.7. Écriture d'objets : ObjectOutputStream
4. Flux d'entrée
4.1. Introduction
4.2. Lecture de caractères, classe Reader
4.3. Bufferisation, lecture ligne par ligne
4.4. Lecture d'octets : InputStream
4.5. Lecture de types primitifs : DataInputStream
4.6. Lecture d'objets : ObjectInputStream
5. Lecture et écriture de flux croisés
5.1. Introduction
5.2. Lire des caractères sur un flux binaire : classe InputStreamReader
5.3. Écrire des caractères sur un flux binaire : classe OutputStreamWriter
5.4. Remarque sur les jeux de caractères
6. Serialization d'objets
6.1. Enjeu de la sérialization d'objets
6.2. Serialization d'un objet
6.3. Sérialization d'une grappe d'objets
6.4. Première surcharge : méthode writeObject() readObject()
6.5. Deuxième surcharge : utilisation d'un externalizer
6.6. Troisième surcharge : utilisation d'un objet proxy
7. Flux compressés
7.1. Introduction
7.2. Flux de type gzip
7.3. Flux de type zip

1. Un premier exemple

1.1. Aperçu général, cycle de vie

Avant de pouvoir travailler sur des fichiers Java, il faut s'assurer qu'un environnement de développement a bien été installé sur la machine sur laquelle on se trouve. Qu'il s'agisse d'une machine Windows, Linux, d'un Macintosh ou d'une station de travail, on doit avoir un environnement "JDK" (Java Development Kit) quelque part sur sa machine. Dans le répertoire racine de l'installation de ce "JDK" se trouve un répertoire bin, dont le contenu doit être accessible via la variable PATH, sous Unix, Linux ou Windows. Un programme Java est tout d’abord écrit sous forme de code source dans un ou plusieurs fichiers de type texte. Par convention, ces fichiers portent l’extension .java. Nous verrons dans la suite qu'il existe au moins deux autres types de contraintes sur le nommage de ces fichiers, ainsi que la façon dont on les range dans des répertoires. Pour pouvoir être exécutés, ces fichiers doivent être compilés, ensemble ou séparément. Ce que l'on entend par "compilation" en Java n'est pas tout à fait la même chose que dans un langage tel que le C ou le C++. Dans ces langages, le code compilé est un code binaire, directement exécutable sur un microprocesseur, et donc dépendant de lui et de l'OS sur lequel il est appelé à fonctionner. En Java, le "code compilé" est en fait un "byte-code", code binaire exécuté dans une machine virtuelle, indépendant de l'ordinateur sur lequel il va fonctionner, et de son OS. Le compilateur est une application fournie avec le JDK, qui s’appelle javac . La commande de base pour compiler le fichier application.java est donc :
 $ javac application.java
Avant de tenter de compiler des programmes Java, il faut donc s’assurer que l’on a bien accès à l’application javac , au moins depuis son répertoire de travail. S’il ne donne pas de messages d’erreur, javac produit alors un fichier au même endroit que application.java : application.class. C’est ce fichier qui contient le code qui va être exécuté dans la machine virtuelle Java. Ce fichier est au format binaire. Nous reverrons dans la suite que, quelle que soit la machine sur laquelle on travaille, le contenu binaire de ce fichier ne varie pas. Il ne s'agit pas d'un exécutable à proprement parler, au sens où on l'entend en C ou en C++, mais plutôt d'un code binaire, appelé "byte code", indépendant de la machine sur laquelle ce pseudo-exécutable va être utilisé. On peut donc copier ce fichier sur toute autre machine que celle sur laquelle il a été compilé, et l'exécuter. La notion de cross-compilation n'existe pas en Java. Notons que l’on peut compiler d’un seul coup plusieurs fichiers dans un même répertoire, par la commande :
 $ javac *.java
Les fichiers .class portent les mêmes noms que les fichiers sources. On a accès à l’ensemble des options de javac en tapant la commande :
 $ javac -h
L’exécution du programme est appelée par la commande suivante :
 $ java application
Là encore, java est une application livrée avec le JDK, qui se trouve dans le même répertoire que javac . Cette commande lance la machine virtuelle Java (JVM, Java Virtual Machine), capable d'exécuter le "byte code". On ne précise pas l’extension .class dans ce cas. On voit ici que application est donnée comme argument de la commande java . Notons tout de suite que l’on peut rassembler plusieurs fichiers .class dans un fichier .zip ou .jar, et que l’on peut exécuter directement un programme en donnant comme argument le nom du fichier .zip ou .jar. Nous reverrons en détails ce mécanisme.

1.2. Un premier programme

Il est de tradition de commencer tout apprentissage d’un langage par l’écriture d’un petit programme capable d’écrire « Bonjour le monde » sur un écran. Il semble même que ce soit une caractéristique de tout langage de programmation évolué, et de nombreux frameworks. Java tombant dans cette catégorie, il paraît indispensable de sacrifier à cette tradition ! Écrivons un premier programme Java. Cela nous permettra d’une part de clarifier la procédure de compilation et d’exécution, et d’autre part d’examiner la structure générale des programmes Java.

Exemple 1. J'écris Bonjour le monde en Java !

public  class Bonjour {  
	 public  static  void main (String [] arguments) {  
		System.out.println("Bonjour le monde") ;  
		System.exit(0) ;  
	}
}

On remarque tout d'abord que le code est contenu dans un bloc : public class Bonjour { ... }. Tout comme dans d’autres langages, un code Java se découpe en blocs, délimités par des accolades. Tout code Java doit être déclaré à l’intérieur d’une classe, et la fonction de ce bloc est de délimiter une telle classe. À l’intérieur d’une classe, on peut déclarer trois types de choses : des champs, des méthodes et des blocs. La première déclaration que l’on trouve dans ce bloc est celle d’une méthode : public static void main(...). Cette méthode main a un statut particulier : c’est elle qui est appelée en premier quand on lance un programme Java. À l’intérieur de ce bloc se trouvent deux commandes. La première affiche Bonjour le monde sur la console, la deuxième ferme le programme. Nous venons d’écrire notre premier programme Java.

1.3. Programmes, applets, servlets, etc...

Il existe en fait de nombreuses façons d'exécuter un programme Java. Le premier exemple que nous avons vu consiste à écrire une classe comportant une méthode main, et à l'exécuter. L'autre façon d'exécuter un code Java, consiste à confier ce code à un container, qui va se charger de son exécution dans un environnement que l'on appellera "managé". Il existe plusieurs types de container, et à chacun est associé un type d'application Java. On peut dresser la liste suivante :
  • une applet s'exécute dans un navigateur Web ;
  • une servlet est exécutée dans un serveur Web ;
  • un EJB (enterprise Java bean) dans un serveur JEE, aussi appelé serveur d'application.
Ces programmes, exécutés dans des containers, ne s'écrivent pas exactement de la même façon qu'une application indépendante (on dira stand-alone en anglais). En particulier, ils n'ont pas de méthode main. Il existe de nombreuses autres contraintes, à la fois dans leur écriture et dans leur exécution, notamment du point de vue de la sécurité. Dans le cas des applets, ce point est même crucial : une applet est une application téléchargée au travers de l'Internet, qui s'exécute sur la machine d'un internaute. La machine Java doit donc vérifier de façon très stricte que cette application respecte la sécurité de la machine sur laquelle elle s'exécute.
Java langage & API
Retour au blog Java le soir
Cours & Tutoriaux