Uploaded by THEGYMLABO

Java Avancé : Concepts et rappels

advertisement
Java Avancé
Pr. F. TOUFIK
2022/2023
Java Avancé
Introduction
Rappel
•
Java est un langage de programmation orienté objet de haut niveau, basé sur des classes.
•
Développé et publié par Sun Microsystems en 1995.
•
Actuellement Java appartient à Oracle.
•
Java s'exécute sur diverses plates-formes, telles que Windows, Mac OS et les différentes versions
d'UNIX.
•
Java est utilisé pour développer des applications mobiles, des applications Web, des applications
Desktop, ….
•
Java est un langage de programmation permet aux programmeurs de write once, run anywhere
(WORA).
•
Cela signifie que le code Java compilé peut s'exécuter sur toutes les plates-formes prenant en
charge Java sans qu'il soit nécessaire de le recompiler.
F. TOUFIK
2
Java Avancé
Introduction
Rappel
• Java est un langage:
•
Orienté objet: En Java, tout est un objet. Java peut être facilement étendu car il est basé sur le modèle Objet.
•
Indépendant de la plate-forme: Contrairement à de nombreux autres langages de programmation, notamment
C et C ++, lorsque Java est compilé, il n'est pas compilé dans une machine spécifique à la plate-forme, mais
plutôt dans un code binaire indépendant de la plate-forme. Ce code binaire (bytecode) est interprété par la
machine virtuelle (JVM) sur la plate-forme sur laquelle il est exécuté.
•
Simple: Java est conçu pour être facile à apprendre. Si vous comprenez le concept de base de la POO, il serait
facile à maîtriser.
•
Architecture-neutre: Le compilateur Java génère un format de fichier objet indépendant de l'architecture, ce
qui rend le code compilé exécutable sur de nombreux processeurs, avec la présence du Java Runtime System.
F. TOUFIK
3
Java Avancé
Introduction
Rappel
• Java est un langage:
•
Multithread: Avec la fonctionnalité multithread de Java, il est possible d'écrire des programmes
capables d'effectuer plusieurs tâches simultanément. Cette fonctionnalité permet aux développeurs
de créer des applications interactives qui peuvent fonctionner sans problème.
•
Interprété: Le code binaire Java est traduit en instructions machine natives. Le processus de
développement est plus rapide.
F. TOUFIK
•
Performant: Avec l'utilisation de compilateurs Just-In-Time, Java permet des performances élevées.
•
Distribué: Java est conçu pour l'environnement distribué d'Internet.
4
Java Avancé
POO
•
Rappel
En tant que langage doté de l’orientée objet, Java prend en charge les concepts fondamentaux
suivants:
o Classes
o Objets
o Méthodes
o Encapsulation
o Héritage
o Polymorphisme
o Abstraction
F. TOUFIK
5
Java Avancé
POO
•
Rappel
Objet: un objet est une structure définie par un état et un comportement.
•
Exemple : Une voiture a des états: couleur, marque, … ainsi que des comportements: démarrer,
ralentir, freiner,… .
•
•
Un objet est une instance d'une classe.
Classe: Une classe peut être définie comme un modèle/plan directeur qui décrit le
comportement/l'état que l'objet de son type prend en charge.
•
F. TOUFIK
Une classe peut contenir plusieurs type de variables:
•
Les variables locales.
•
Les variables d’instance.
•
Les variables de Classe.
6
Java Avancé
Les variables
•
Rappel
Les variables locales
•
Les variables définies à l'intérieur des méthodes, des constructeurs ou des blocs sont appelées variables locales. La
variable sera déclarée et initialisée dans la méthode et la variable sera détruite lorsque la méthode sera terminée.
•
Les variables d’instance
•
Les variables d'instance sont des variables au sein d'une classe mais en dehors de toute méthode. Ces variables sont
initialisées lors de l'instanciation. Les variables d'instance sont accessibles depuis n'importe quelle méthode,
constructeur ou bloc de cette classe.
•
Les variables de classe
•
Les variables de classe sont des variables déclarées dans une classe, en dehors de toute méthode, avec le mot-clé
static.
F. TOUFIK
7
Java Avancé
Les constructeurs
Rappel
• Les constructeurs
•
Un constructeur initialise un objet lors de sa création. Elle porte le même nom que sa classe et est
syntaxiquement similaire à une méthode. Cependant, les constructeurs n'ont pas de type de retour
explicite.
•
En règle générale, on utilise un constructeur pour donner des valeurs initiales aux variables
d'instance définies par la classe ou pour effectuer toute autre procédure de démarrage requise pour
créer un objet entièrement formé.
•
Toutes les classes ont des constructeurs. Java fournit automatiquement un constructeur par défaut
qui initialise toutes les variables membres à (zéro, null, ‘’’’). Cependant, une fois on définit notre
propre constructeur, le constructeur par défaut n'est plus utilisé.
F. TOUFIK
8
Java Avancé
Les modificateurs
Rappel
• Les modificateurs
•
•
Java a une grande variété de modificateurs, y compris les suivants:
•
Les modificateurs de contrôle d’accès.
•
Les modificateurs sans accès.
Pour utiliser un modificateur, on ajoute son mot-clé dans la définition d'une classe, d'une méthode
ou d'une variable. Le modificateur précède le reste de l'instruction, comme dans l'exemple suivant.
F. TOUFIK
9
Java Avancé
Les modificateurs
Rappel
• Les modificateurs de contrôle d’accès
•
Java fournit un certain nombre de modificateurs d'accès pour définir les niveaux d'accès pour les
classes, les variables, les méthodes et les constructeurs. Les quatre niveaux d'accès sont:
F. TOUFIK
•
Visible par le package (valeur par défaut). Aucun modificateur n'est nécessaire.
•
Visible uniquement à la classe (private).
•
Visible par toutes les entités (public).
•
Visible par le package et toutes les sous-classes (protected).
10
Java Avancé
Les modificateurs
Rappel
• Les modificateurs sans accès
•
Java fournit un certain nombre de modificateurs sans accès pour obtenir de nombreuses autres
fonctionnalités comme:
F. TOUFIK
•
static pour créer des méthodes et des variables de classe.
•
final pour finaliser les implémentations des classes, des méthodes et des variables.
•
abstract pour créer des classes et des méthodes abstraites.
•
Les modificateurs synchronized et volatile, qui sont utilisés pour les threads.
11
Java Avancé
Encapsulation
•
Rappel
L'encapsulation en Java est le mécanisme d‘envelopper les données (variables) et le code agissant sur
les données (méthodes) en une seule unité.
•
Dans l'encapsulation, les variables d'une classe seront cachées des autres classes et ne seront
accessibles que par les méthodes de leur classe actuelle. Par conséquent, il est également connu
sous le nom de masquage de données (data hiding).
•
Pour réaliser l'encapsulation en Java:
•
Déclarez les variables d'une classe comme privées (private).
•
Ajoutez des méthodes setter et getter publiques (public)
pour modifier et afficher les valeurs des variables.
F. TOUFIK
12
Java Avancé
Héritage
•
Rappel
L'héritage peut être défini comme le processus par lequel une classe acquiert les propriétés (méthodes et
champs) d'une autre.
•
Avec l'utilisation de l'héritage, les informations sont rendues gérables dans un ordre hiérarchique.
•
extends est le mot clé utilisé pour hériter des propriétés d'une classe.
•
Voici un exemple démontrant l'héritage Java. Dans cet exemple, vous pouvez observer deux classes, à savoir
Personne et Etudiant.
•
En utilisant le mot clé extends, Etudiant hérite la méthodes calculerAge() et afficherInfo() de la classe Personne.
•
Dans le programme donné, lorsqu'un objet de la classe Etudiant est créé, une copie du contenu de la superclasse
est faite à l'intérieur de celui-ci. C'est pourquoi, en utilisant l'objet de la sous-classe, vous pouvez accéder aux
membres d'une super-classe.
F. TOUFIK
13
Java Avancé
Héritage
•
Rappel
La variable de référence super-class peut contenir l'objet de sous-classe, mais en utilisant cette
variable, vous ne pouvez accéder qu'aux membres de la superclasse, donc pour accéder aux
membres des deux classes, il est recommandé de toujours créer une variable de référence à la sousclasse.
•
Une sous-classe hérite de tous les membres (champs, méthodes) de sa super-classe. Les constructeurs ne sont
pas des membres, ils ne sont donc pas hérités par les sous-classes, mais le constructeur de la super-classe
peut être appelé à partir de la sous-classe.
•
Le mot-clé super est utilisé pour:
•
Différencier les membres de la super-classe des membres
de la sous-classe, s'ils ont les mêmes noms.
•
F. TOUFIK
Invoquer le constructeur de la super-classe à partir de la sous-classe.
14
Java Avancé
Abstraction
Rappel
•
Selon le dictionnaire, l'abstraction est la qualité de traiter des idées plutôt que des événements.
•
Prenant le cas de l’e-mail, des détails complexes tels que ce qui se passe dès que vous envoyez un e-mail,
comme le protocole utilisé par votre serveur de messagerie sont cachés à l'utilisateur.
•
Par conséquent, pour envoyer un e-mail, il vous suffit de saisir le contenu, de mentionner l'adresse du
destinataire et de cliquer sur envoyer.
•
De même dans la programmation orientée objet, l'abstraction est un processus de masquage des détails
d'implémentation à l'utilisateur, seule la fonctionnalité sera fournie à l'utilisateur. En d'autres termes,
l'utilisateur aura les informations sur ce que fait l'objet au lieu de savoir comment il le fait.
•
F. TOUFIK
En Java, l'abstraction est réalisée à l'aide de classes abstraites et d'interfaces.
15
Java Avancé
Abstraction
Rappel
• Classe Abstraite
•
Une classe qui contient le mot-clé abstract dans sa déclaration est appelée classe abstraite.
•
Les classes abstraites peuvent contenir des méthodes abstraites, c'est-à-dire des méthodes sans
définition ( public void get(); )
•
Mais, si une classe a au moins une méthode abstraite, alors la classe doit être déclarée abstraite.
•
Si une classe est déclarée abstraite, elle ne peut pas être instanciée.
•
Si vous héritez d'une classe abstraite, vous devez fournir des implémentations à toutes les
méthodes abstraites qu'elle contient.
F. TOUFIK
16
Java Avancé
Interfaces
•
Rappel
Une interface est similaire à une classe. C'est une collection de méthodes abstraites. Une classe
implémente une interface, automatiquement elle hérite les méthodes abstraites de l'interface.
•
Outre les méthodes abstraites, une interface peut également contenir des constantes, des méthodes
par défaut, des méthodes statiques et des types imbriqués. Les corps de méthode existent
uniquement pour les méthodes par défaut et les méthodes statiques.
•
Sauf si la classe qui implémente l'interface est abstraite, toutes les méthodes de l'interface doivent
être définies dans la classe.
F. TOUFIK
17
Java Avancé
Interfaces
•
F. TOUFIK
Rappel
Une interface est différente d'une classe de plusieurs manières, notamment:
•
Vous ne pouvez pas instancier une interface.
•
Une interface ne contient aucun constructeur.
•
Toutes les méthodes d'une interface sont abstraites.
•
Une interface ne peut pas contenir de champs d'instance.
•
Les seuls champs pouvant apparaître dans une interface doivent être déclarés à la fois static et final.
•
Une interface n'est pas étendue par une classe ; il est implémenté par une classe.
•
Une interface peut étendre plusieurs interfaces.
18
Java Avancé
Interfaces
Rappel
•
Le mot clé interface est utilisé pour déclarer une interface.
•
Une interface est implicitement abstraite.
•
Vous n'avez pas besoin d'utiliser le mot clé abstract lors de la déclaration d'une interface.
•
Chaque méthode d'une interface est aussi implicitement abstraite, de sorte que le mot-clé abstract
n'est pas nécessaire.
•
Les méthodes d'une interface sont implicitement publiques.
•
Lorsqu'une classe implémente une interface, vous pouvez considérer la classe comme signant un
contrat, acceptant d'exécuter les comportements spécifiques de l'interface. Si une classe n'exécute
pas tous les comportements de l'interface, la classe doit se être abstraite.
F. TOUFIK
19
Java Avancé
Interfaces
•
Rappel
Pour implémenter une interface, on utilise le mot clé implements.
•
Lors du surcharge des méthodes définies dans les interfaces, il y a plusieurs règles à suivre:
•
La signature de la méthode d'interface et le même type ou sous-type de retour doivent être conservés lors
de la redéfinition des méthodes.
•
Une classe d'implémentation elle-même peut être abstraite et si c'est le cas, les méthodes d'interface n'ont
pas besoin d'être implémentées.
•
Lors de l'implémentation des interfaces, il existe plusieurs règles:
•
Une classe peut implémenter plusieurs interfaces à la fois.
•
Une classe ne peut étendre qu'une seule classe, mais implémenter de nombreuses interfaces.
•
Une interface peut étendre une autre interface, de la même manière qu'une classe peut étendre une autre
classe.
F. TOUFIK
20
Java Avancé
Polymorphisme
•
Rappel
Le polymorphisme est la capacité d'un objet à prendre plusieurs formes. L'utilisation la plus courante du
polymorphisme dans la POO se produit lorsqu'une référence de classe parent est utilisée pour faire référence à
un objet de classe enfant.
•
Tout objet Java qui peut réussir plus d'un test IS-A est considéré comme polymorphe. En Java, tous les objets
Java sont polymorphes puisque tout objet passera le test IS-A pour son propre type et pour la classe Object.
•
Il est important de savoir que le seul moyen possible d'accéder à un objet est via une variable de référence. Une
variable de référence ne peut être que d'un seul type. Une fois déclaré, le type d'une variable de référence ne peut
pas être modifié.
•
La variable de référence peut être réaffectée à d'autres objets à condition qu'elle ne soit pas déclarée finale. Le type
de la variable de référence déterminerait les méthodes qu'elle peut invoquer sur l'objet.
•
Une variable de référence peut faire référence à n'importe quel objet de son type déclaré ou à n'importe quel
sous-type de son type déclaré. Une variable de référence peut être déclarée comme une classe ou un type
F. TOUFIK
d'interface.
21
Java Avancé
Les Exceptions
•
Une exception est un problème qui survient lors de l'exécution d'un programme. Lorsqu'une
exception se produit, le déroulement normal du programme est interrompu et le
programme/l'application se termine anormalement, ce qui n'est pas recommandé. Par
conséquent, ces exceptions doivent être gérées.
•
Une exception peut se produire pour de nombreuses raisons différentes. Voici quelques
scénarios dans lesquels une exception se produit.
F. TOUFIK
•
Un utilisateur a entré une donnée invalide.
•
Un fichier qui doit être ouvert est introuvable.
•
Une connexion réseau a été perdue au milieu des communications.
22
Java Avancé
Les Exceptions
•
Certaines de ces exceptions sont causées par une erreur de l'utilisateur, d'autres par une
erreur du programmeur et d'autres par des ressources physiques qui ont échoué d'une
manière ou d'une autre.
•
Sur cette base, nous avons trois catégories d'exceptions. On doit les comprendre pour savoir
comment fonctionne la gestion des exceptions en Java.
1. Les exceptions contrôlées.
2. Les exceptions non contrôlées.
3. Les erreurs.
F. TOUFIK
23
Java Avancé
Les Exceptions
• Les exceptions contrôlées (checked exception)
•
Une exception contrôlée est une exception qui est vérifiée (notifiée) par le compilateur au moment de
la compilation, elles sont également appelées exceptions au moment de la compilation. Ces
exceptions ne peuvent pas simplement être ignorées, le programmeur doit gérer ces exceptions.
•
Par exemple, si on utilise la classe FileReader dans notre programme pour lire les données d'un
fichier, si le fichier spécifié dans le constructeur est introuvable, une FileNotFoundException se
produit et le compilateur invite le programmeur à gérer l'exception.
F. TOUFIK
24
Java Avancé
Les Exceptions
• Les exceptions non contrôlées (unchecked exception)
•
Une exception non contrôlée est une exception qui se produit au moment de l'exécution. Celles-ci
sont également appelées les exceptions d'exécution (Runtime exception). Ceux-ci incluent des bugs
de programmation, tels que des erreurs de logique ou une mauvaise utilisation d'une API. Les
exceptions d'exécution sont ignorées au moment de la compilation.
•
Par exemple, si on déclare un tableau de taille 3 dans notre programme et on veut récupérer le 4-ème
élément du tableau, l’exception ArrayIndexOutOfBoundsException se produit.
F. TOUFIK
25
Java Avancé
Les Exceptions
• Les erreurs
•
Ce ne sont pas du tout des exceptions, mais des problèmes qui surgissent au-delà du
contrôle de l'utilisateur ou du programmeur.
•
Les erreurs sont généralement ignorées dans le code car on ne peut rien faire à propos
d'une erreur.
•
Par exemple, si un débordement de pile (stack overflow) se produit, une erreur se
produira.
•
F. TOUFIK
Ils sont également ignorés au moment de la compilation.
26
Java Avancé
Les Exceptions
• Hiérarchie des exceptions
•
Toutes les classes d'exception sont des sous-types de la classe java.lang.Exception. La classe Exception
est une sous-classe de la classe Throwable. Outre la classe d’Exception, il existe une autre sous-classe
appelée Error qui est dérivée de la classe Throwable.
•
Les erreurs sont des conditions anormales qui se produisent en cas de pannes graves, elles ne sont
pas gérées par les programmes Java.
Object
Throwable
Error
Exception
RuntimeException
IOException
SQLException
F. TOUFIK
27
Java Avancé
Les Exceptions
• Les méthodes des exceptions
•
Voici la liste des méthodes importantes disponibles dans la classe Throwable.
Méthode
F. TOUFIK
Description
public String getMessage()
Renvoie un message détaillé sur l'exception qui s'est produite. Ce message est
initialisé dans le constructeur Throwable.
public Throwable getCause()
Renvoie la cause de l'exception.
public String toString()
Renvoie le nom de la classe concaténé avec le résultat de getMessage().
public void printStackTrace()
Imprime le résultat de toString() avec la trace de la pile sur System.err, le flux de
sortie d'erreur.
public StackTraceElement [] getStackTrace()
Renvoie un tableau contenant chaque élément de la trace de la pile. L'élément à
l'index 0 représente le haut de la pile des appels et le dernier élément du tableau
représente la méthode en bas de la pile des appels.
public Throwable fillInStackTrace()
Remplit la trace de pile de cet objet Throwable avec la trace de pile actuelle.
28
Java Avancé
Les Exceptions
• Interception des exceptions
•
Une méthode intercepte une exception en utilisant une combinaison des mots-clés try et catch.
•
Un bloc try/catch est placé autour du code susceptible de générer une exception.
•
Le code dans un bloc try/catch est appelé code protégé, et la syntaxe pour utiliser try/catch ressemble
à ce qui suit:
F. TOUFIK
29
Java Avancé
Les Exceptions
• Interception des exceptions
•
Le code sujet aux exceptions est placé dans le bloc try. Lorsqu'une exception se produit,
cette exception est gérée par le bloc catch associé. Chaque bloc try doit être
immédiatement suivi par un bloc catch ou d'un bloc finally.
•
Une instruction catch implique la déclaration du type d'exception qu’on veut attraper.
•
Si une exception se produit dans le code protégé, le ou les blocs catch qui suivent le try
sont vérifiés.
•
Si le type d'exception qui s'est produit est répertorié dans un bloc catch, l'exception est
transmise au bloc catch comme un argument est transmis à un paramètre d’une méthode.
F. TOUFIK
30
Java Avancé
Les Exceptions
• Interception des exceptions
•
Exemple: Voici un tableau déclaré avec 3 éléments. Ensuite, le code tente d'accéder au
4ème élément du tableau qui lève une exception.
F. TOUFIK
31
Java Avancé
Les Exceptions
• Multiple blocs de catch
•
Un bloc try peut être suivi de plusieurs blocs catch. La syntaxe de plusieurs blocs catch
ressemble à ce qui suit:
F. TOUFIK
32
Java Avancé
Les Exceptions
• Multiple blocs de catch
•
Les instructions précédentes illustrent trois blocs catch.
•
Si une exception se produit dans le code protégé, l'exception est renvoyée au premier
bloc catch de la liste.
•
Si le type de données de l'exception levée correspond à ExceptionType1, elle y est
interceptée. Si ce n'est pas le cas, l'exception est transmise à la deuxième instruction catch.
Cela continue jusqu'à ce que l'exception soit interceptée ou tombe à travers toutes les
catch.
F. TOUFIK
33
Java Avancé
Les Exceptions
• Multiple blocs de catch
•
Exemple: Voici un segment de code montrant comment utiliser plusieurs instructions
try/catch.
F. TOUFIK
34
Java Avancé
Les Exceptions
• Le bloc Finally
•
Le bloc finally suit un bloc try ou un bloc catch. Un bloc de code finally s'exécute toujours,
quelle que soit l'occurrence d'une exception.
•
L'utilisation d'un bloc finally permet d'exécuter toutes les instructions de type nettoyage,
peu importe ce qui se passe dans le code protégé.
•
F. TOUFIK
Le code suivant présente l’utilisation du bloc finally:
35
Java Avancé
Les Exceptions
• Les exceptions définies par l’utilisateur
•
On peut créer nos propres exceptions en Java.
•
pour créer un exception on doit respecter les points suivants:
•
Toutes les exceptions doivent être un enfant de Throwable.
•
Pour créer une exception contrôlée (checked exception) , l’exception définie doit étendre la classe
Exception.
•
Pour créer une exception non contrôlée d’exécution (unchecked exception), l’exception définie
doit étendre la classe RuntimeException.
F. TOUFIK
36
Java Avancé
Les Exceptions
• Les exceptions définies par l’utilisateur
•
Pour illustrer l’utilisation de l’exception définie par l’utilisateur, la classe Personne
contient une méthode verser() qui lève l’exception SoldeInsuffisantException.
F. TOUFIK
37
Java Avancé
Fichiers & IO
• Le Package IO
•
Le package java.io contient presque toutes les classes pour effectuer des entrées (input) et
des sorties (output) (E/S) (I/O) en Java.
•
Tous ces flux (Stream) représentent une source d'entrée et une destination de sortie.
•
Un Stream peut être défini comme une séquence de données. Il existe deux types de
Stream:
•
InPutStream : Le InputStream est utilisé pour lire des données à partir d'une source.
•
OutPutStream : Le OutputStream est utilisé pour écrire des données vers une destination.
Source
F. TOUFIK
Programme
Destination
38
Java Avancé
Fichiers & IO
• InputStream
•
Un InputStream est utilisé pour lire les données à partir d'une source dans une application
Java.
•
Les données peuvent être n'importe quoi, un fichier, un tableau, un périphérique ou un
socket.
•
En Java, la classe java.io.InputStream est la classe de base pour tous les flux d'entrée Java
IO.
InputStream
ByteArrayInputStream
FileInputStream
PipedInputStream
ObjectInputStream
FilterInputStream
DataInputStream
F. TOUFIK
BufferedInputStream
PushBackInputStream
39
Java Avancé
Fichiers & IO
• Les méthodes InputStream
Méthode
Description
read()
utilisée pour lire le prochain octet de données du flux d'entrée. La valeur byte est
transmise sur une échelle de 0 à 255. Si aucun octet n'est libre car la fin du flux est
arrivée, la valeur -1 est transmise.
mark(int arg)
utilisée pour marquer la position actuelle du flux d'entrée. Il définit read à limit,
c'est-à-dire le nombre maximum d'octets pouvant être lus avant que la position de la
marque ne devienne invalide.
reset()
invoquée par la méthode mark(). Il change la position du flux d'entrée à la position
marquée.
close()
utilisée pour fermer le flux d'entrée et libère les ressources système associées à ce
flux.
read(byte [] arg)
utilisée pour lire le nombre d'octets de arg.length du flux d'entrée au tableau de
tampons arg. Les octets lus par la méthode read() sont renvoyés sous la forme d'un
int. Si la longueur est zéro, aucun octet n'est lu et 0 est renvoyé à moins qu'il y ait un
effort pour lire au moins un octet.
skip(long arg)
utilisée pour ignorer les octets arg dans le flux d'entrée.
markSupported()
teste si inputStream prend en charge les méthodes de marquage et de réinitialisation.
La méthode markSupported de Java IO InputStream renvoie false par défaut.
F. TOUFIK
40
Java Avancé
Fichiers & IO
• OutputStream
•
Un OutputStream est utilisé pour écrire les données (un fichier, un tableau, un
périphérique ou un socket) vers une destination.
•
En Java, la classe java.io.OutputStream est la classe de base pour tous les flux de sortie Java
IO.
OutputStream
ByteArrayOutputStream
FileOutputStream
PipedOutputStream
ObjectOutputStream
FilterOutputStream
DataOutputStream
F. TOUFIK
BufferedOutputStream
PushBackOutputStream
41
Java Avancé
Fichiers & IO
• Les méthodes OutputStream
Méthode
Description
flush()
utilisée pour vider le outputStream Cette méthode force l'écriture des octets de sortie
mis en mémoire tampon.
close()
utilisée pour fermer le outputStream et libérer les ressources système associées au
flux.
write(int b)
utilisée pour écrire l'octet spécifié dans le outputStream.
write(byte [] b)
utilisée pour écrire des octets de b.length depuis le tableau d'octets spécifié vers
outputStream.
F. TOUFIK
42
Java Avancé
Fichiers & IO
• Les types des flux (stream) dans java io
OutputStream
BufferedReader
FileOutputStream
FileReader
DataOutputStream
InputStreamReader
BufferedOutputStream
OutputStreamReader
PrintStream
F. TOUFIK
ByteStream
Stream
CharacterStream
Reader
InputStream
PrintWriter
FileInputStream
Writer
DataInputStream
BufferedWriter
BufferedInputStream
FileWriter
43
Java Avancé
Fichiers & IO
• Byte Stream
•
Les Byte Stream Java sont utilisés pour effectuer l'entrée et la sortie d'octets de 8 bits (byte).
•
Les classes les plus fréquemment utilisées sont FileInputStream et FileOutputStream.
•
Voici un exemple qui utilise ces deux classes pour copier un fichier d'entrée dans un
fichier de sortie:
F. TOUFIK
44
Java Avancé
Fichiers & IO
• Character Streams
•
Les flux de caractères (Character Stream) sont ceux qui sont utilisés pour implémenter l'entrée et la
sortie avec 16 bits Unicode.
•
Plusieurs classes sont associées à des flux de caractères en Java, mais les classes les plus couramment
utilisées sont FileReader et FileWriter.
•
L'exemple ci-dessus, utilise ces deux classes pour copier un fichier d'entrée (ayant des caractères
Unicode) dans un fichier de sortie:
F. TOUFIK
45
Java Avancé
Fichiers & IO
• Standard Streams
•
Tous les langages de programmation prennent en charge les (IO) standard où le programme de
l'utilisateur peut prendre une entrée à partir d'un clavier, puis produire une sortie sur l'écran de
l'ordinateur.
•
C ou C++, utilise trois dispositifs standard STDIN, STDOUT et STDERR. De même, Java fournit les
trois flux standard suivants:
•
Entrée standard : Ceci est utilisé pour alimenter les données au programme et généralement le
clavier est utilisé comme flux d'entrée standard et représenté par System.in.
•
Sortie standard : Ceci est utilisé pour afficher les données produites par le programme et
généralement l’écran de l'ordinateur est utilisé comme flux de sortie standard et représenté par
System.out.
•
Erreur standard : Ceci est utilisé pour afficher les données d'erreur produites par le programme
et généralement l’écran de l‘ordinateur est utilisé comme flux d'erreur standard et représenté
par System.err.
F. TOUFIK
46
Java Avancé
Fichiers & IO
• Exemple
F. TOUFIK
47
Java Avancé
Fichiers & IO
• Les dossiers
•
Un répertoire est un fichier qui peut contenir une liste des fichiers ou des répertoires.
•
On utilise l’objet File pour créer des répertoires, pour lister les fichiers disponibles dans un
répertoire,….
•
Il existe deux méthodes utiles de la class File qui peuvent être utilisées pour créer des répertoires:
•
La méthode mkdir( ) crée un répertoire, true en cas de succès et false en cas d'échec.
•
Un échec indique que le chemin spécifié dans l'objet File existe déjà ou que le répertoire ne peut
pas être créé car le chemin complet n'existe pas encore.
F. TOUFIK
•
La méthode mkdirs() crée à la fois un répertoire et tous les parents du répertoire.
•
L'exemple suivant crée le répertoire "/user/toufik/desktop/test"
48
Java Avancé
Fichiers & IO
• Les dossiers
•
On peut utiliser la méthode list() fournie par l'objet File pour lister tous les fichiers et répertoires
disponibles dans un répertoire comme suit:
F. TOUFIK
49
Java Avancé
JDBC
• Qu'est-ce que JDBC (Java Database Connectivity)
•
JDBC est une API Java permettant à une application Java de se connecter à une base de données,
d'envoyer des requêtes SQL et de traiter les résultats.
• Objectifs de JDBC
•
Établir une communication transparente entre une application Java et une base de données
relationnelle.
•
Créer une connexion à la base de données à l'aide des informations de connexion (URL, nom
d'utilisateur, mot de passe).
•
Envoyer des requêtes SQL à la base de données pour effectuer des opérations comme la sélection,
l'insertion, la mise à jour et la suppression.
•
F. TOUFIK
Récupérer et manipuler les résultats des requêtes dans l'application Java.
50
Java Avancé
•
JDBC
Architecture JDBC
1.
JDBC API
•
Ensemble d'interfaces et de classes pour interagir avec la base de données
(Connection, Statement, ResultSet, …).
2. Driver Manager, Gestionnaire des Pilotes
•
JDBC API
Driver Manager
Gère les pilotes JDBC, enregistre et fournit des connexions à la base de données.
3. JDBC Driver, Pilote JDBC
•
Java App
JDBC
Driver
JDBC
Driver
MySQL
Oracle
un ensemble de classes Java qui implémente l'interface JDBC pour une base de
données spécifique.
•
F. TOUFIK
Le choix du pilote dépend du type de base de données utilisé.
51
Java Avancé
JDBC
• Driver Manager
•
Le DriverManager de JDBC joue un rôle crucial dans la gestion des pilotes JDBC et dans la fourniture de connexions
à la base de données.
•
Depuis JDBC 4.0 (Java 6 et versions ultérieures), l'enregistrement explicite du pilote avec Class.forName n'est plus
nécessaire.Le pilote JDBC peut être chargé automatiquement à partir du classpath lorsqu'une connexion est
demandée.
•
F. TOUFIK
Exemple de création de connexion (MySQL)
52
Java Avancé
•
JDBC
Exécution de Requêtes SQL
•
Statement et PreparedStatement sont des interfaces de l'API JDBC permettant d'exécuter des requêtes SQL. Ces
interfaces fournissent des méthodes pour envoyer des instructions SQL à la base de données.
•
Dans cet exemple, un objet Statement est créé à partir de la connexion, et une requête de sélection est exécutée à
l'aide de la méthode executeQuery(). Le résultat est stocké dans un objet ResultSet.
F. TOUFIK
53
Java Avancé
JDBC
•
Exemple d’insertion avec PreparedStatement
•
Dans cet exemple, un objet PreparedStatement est utilisé pour exécuter une requête SQL d'insertion avec des paramètres.
Les valeurs des paramètres sont définies à l'aide des méthodes setXxx() et la requête est exécutée avec la méthode
executeUpdate(). La méthode retourne le nombre de lignes affectées par la requête.
F. TOUFIK
54
Java Avancé
•
JDBC
executeQuery Vs executeUpdate
•
executeUpdate et executeQuery sont deux méthodes de l'interface Statement dans JDBC, et ils sont utilisés pour exécuter des
requêtes SQL sur une base de données. Cependant, ils sont utilisés dans des contextes différents en fonction du type de
requête que vous souhaitez exécuter.
1.
executeQuery : Cette méthode est utilisée pour exécuter des requêtes SQL qui retournent un ensemble de résultats,
généralement des lignes de données d'une table. Typiquement, il est utilisé pour les requêtes SELECT.
La méthode executeQuery renvoie un objet ResultSet qui contient les résultats de la requête, et vous pouvez itérer sur cet
objet pour accéder aux données.
2.
executeUpdate : Cette méthode est utilisée pour exécuter des requêtes SQL qui modifient la base de données d'une manière
ou d'une autre, comme les requêtes INSERT, UPDATE ou DELETE. Elle renvoie un entier qui représente le nombre de
lignes affectées par la requête.
La méthode executeUpdate est également utilisée pour exécuter des requêtes DDL (Data Definition Language) telles que la
création ou la suppression de tables, où aucune valeur de résultat n'est renvoyée.
F. TOUFIK
55
Java Avancé
•
JDBC
Utilisation des Batch dans JDBC
•
Les batchs permettent d'exécuter un groupement de plusieurs requêtes SQL en une seule opération.
•
Les batchs dans JDBC offrent une manière efficace d'exécuter plusieurs requêtes en une seule transaction, réduisant ainsi la surcharge des
communications avec la base de données. Cependant, il est important de gérer correctement les erreurs et les transactions pour assurer la
cohérence des données.
F. TOUFIK
56
Java Avancé
•
JDBC
commit() & rollback()
•
Les méthodes commit et rollback sont des méthodes de l'interface Connection dans JDBC et sont utilisées pour gérer les transactions dans une
base de données relationnelle.
1.
commit:
• La méthode commit valide toutes les modifications apportées à la base de données depuis le dernier appel de commit.
• Lorsqu'une transaction est terminée avec succès et que toutes les opérations à l'intérieur de la transaction ont été exécutées avec succès,
vous appelez commit pour confirmer ces changements et les rendre permanents dans la base de données.
• Après l'appel de commit, les changements sont persistants et visibles pour d'autres transactions.
2.
rollback
•
La méthode rollback annule toutes les modifications apportées à la base de données depuis le dernier appel de commit.
•
En cas d'erreur ou d'exception pendant l'exécution d'une transaction, vous pouvez appeler rollback pour annuler tous les changements
effectués au cours de la transaction et ramener la base de données à son état précédent.
•
F. TOUFIK
Cela permet de garantir la cohérence des données malgré une défaillance ou une condition d'erreur.
57
Java Avancé
Generics
• Types Génériques en Java
•
Introduction
•
Les types génériques ont été introduits dans Java pour fournir une façon plus sûre et plus flexible de
manipuler les types.
•
Ils permettent de créer des classes, interfaces et méthodes qui peuvent fonctionner avec différents
types sans sacrifier la sécurité du type.
•
Avantages des types génériques
•
Évite les erreurs de type à la compilation.
•
Réduit le besoin de casting.
•
Écriture de classes et de méthodes génériques qui peuvent être utilisées avec différents types de
données.
F. TOUFIK
58
Java Avancé
Generics
• Syntaxe de base (Classe)
•
Déclaration de classe générique (1)
public class Boite<T> {
private T contenu;
•
Déclaration de classe générique (2)
public class Paire<T, U> {
private T premier;
private U deuxieme;
public T getContenu() {
return contenu;
// Constructeur, getters, setters
}
}
public void setContenu(T contenu) {
this.contenu = contenu;
}
}
F. TOUFIK
59
Java Avancé
Generics
• Syntaxe de base (Méthodes génériques)
•
Déclaration de méthodes génériques dans une classe non générique :
public static <T> T getFirstElement(List<T> liste) {
if (liste.isEmpty()) {
return null;
}
return liste.get(0);
}
•
Wildcards (Jokers) : Utilisation de jokers pour des types inconnus
public void imprimerListe(List<?> liste) {
for (Object element : liste) {
System.out.println(element);
}
}
F. TOUFIK
60
Java Avancé
•
Lambda
Introduction aux Fonctions Lambda
1.
2.
3.
Définition des fonctions lambda
•
Les fonctions lambda sont des expressions anonymes pour créer des fonctions de manière concise.
•
Elles sont également appelées expressions lambda en raison de leur syntaxe compacte.
Avantages des fonctions lambda
•
Réduction de la verbosité du code en comparaison avec les méthodes traditionnelles.
•
Amélioration de la lisibilité du code, en particulier pour les opérations simples.
•
Facilitation de la programmation fonctionnelle en Java.
Contexte historique (introduction dans Java 8)
•
Les fonctions lambda ont été introduites dans Java 8 pour faciliter la programmation fonctionnelle.
•
Elles ont été intégrées pour permettre aux développeurs d'adopter un style de programmation plus concis et
moderne.
F. TOUFIK
61
Java Avancé
•
Lambda
Syntaxe des Fonctions Lambda
1.
2.
3.
4.
F. TOUFIK
Format général d'une fonction lambda
•
(paramètres) -> expression
•
Les paramètres peuvent être absents, un ou plusieurs, et la flèche -> sépare les paramètres de l'expression.
Types de paramètres
•
Paramètres explicites : (int a, int b) -> a + b
•
Inférence de type : (a, b) -> a + b
Expression lambda et instructions lambda
•
Expression lambda : x -> x * x
•
Instructions lambda : { System.out.println("Hello"); }
Utilisation des parenthèses
•
Parenthèses facultatives pour un seul paramètre : x -> x * x
•
Parenthèses nécessaires pour zéro ou plusieurs paramètres : (x, y) -> x + y
62
Java Avancé
Lambda
• Interfaces Fonctionnelles
1.
Introduction aux interfaces fonctionnelles
•
Une interface fonctionnelle a une seule méthode abstraite.
•
Exemple :
@FunctionalInterface
public interface Calculateur {
int calculer(int a, int b);
}
2.
Interface fonctionnelle prédéfinie : java.util.function
•
3.
F. TOUFIK
Fournit diverses interfaces fonctionnelles utiles : Predicate, Consumer, Function, etc.
Exemples d'interfaces fonctionnelles
•
Predicate : Vérifie une condition.
•
Consumer : Effectue une opération sans retour.
•
Function : Transforme un type en un autre.
63
Java Avancé
Lambda
• Références de Méthodes
•
Les références de méthodes sont une simplification syntaxique pour les cas où la lambda ne fait qu'appeler une méthode
existante.
•
Les références de méthodes peuvent rendre le code plus lisible dans certains cas.
•
Il est possible d'utiliser des références de méthodes pour des interfaces fonctionnelles existantes.
List<String> noms = Arrays.asList("Ahmed", "Khadija", "Amine");
noms.forEach(System.out::println);
F. TOUFIK
64
Java Avancé
Lambda
• Consumer
•
Un Consumer représente une opération qui prend un argument et ne retourne aucun résultat.
•
Il est souvent utilisé pour effectuer des actions sur les éléments d'une collection.
List<String> fruits = Arrays.asList("Pomme", "Banane", "Orange");
Consumer<String> afficherFruit = (fruit) -> System.out.println("Fruit : " + fruit);
// Premier exemple Avec For
for (String fruit : fruits) {
afficherFruit.accept(fruit);
}
// Deuxième exemple Avec forEach
fruits.forEach(afficherFruit);
F. TOUFIK
65
Java Avancé
Lambda
• Predicate
•
Un Predicate représente une condition qui peut être évaluée comme vraie ou fausse.
•
Il est fréquemment utilisé pour filtrer des éléments dans une collection.
List<Integer> nombres = Arrays.asList(1, 2, 3, 4, 5, 6);
Predicate<Integer> estPair = (nombre) -> nombre % 2 == 0;
// Premier exemple avec For
List<Integer> nombresPairs = new ArrayList<>();
for (Integer nombre : nombres) {
if (estPair.test(nombre)) {
nombresPairs.add(nombre);
}
}
// Deuxième exemple avec stream()
List<Integer> nombresPairs = nombres.stream()
.filter(estPair)
F. TOUFIK
.collect(Collectors.toList());
66
Java Avancé
Lambda
• Function
•
Une Function prend un argument et produit un résultat.
•
Elle est utilisée pour effectuer une transformation sur les éléments d'une collection.
List<String> noms = Arrays.asList("Ahmed", "Khadija", "Amine");
Function<String, Integer> longueurDuNom = String::length;
// Premier exemple avec for
List<Integer> longueursNoms = new ArrayList<>();
for (String nom : noms) {
longueursNoms.add(longueurDuNom.apply(nom));
}
// Deuxième Exemple avec stream()
List<Integer> longueursNoms = noms.stream()
.map(longueurDuNom)
.collect(Collectors.toList());
F. TOUFIK
67
Java Avancé
Lambda
•
Outre Consumer, Predicate, et Function, Java propose d'autres interfaces fonctionnelles pour des cas spécifiques.
•
BiConsumer prend deux arguments et effectue une opération sans retour.
Map<String, Integer> fruitsEtQuantites = new HashMap<>();
fruitsEtQuantites.put("Pomme", 3);
fruitsEtQuantites.put("Banane", 5);
fruitsEtQuantites.put("Orange", 2);
BiConsumer<String, Integer> afficherFruitEtQuantite = (fruit, quantite) ->
System.out.println("Fruit : " + fruit + ", Quantité : " + quantite);
fruitsEtQuantites.forEach(afficherFruitEtQuantite);
•
BiPredicate prend deux arguments et évalue une condition comme vraie ou fausse.
BiPredicate<Integer, Integer> estPlusGrandQue = (a, b) -> a > b;
boolean resultat = estPlusGrandQue.test(10, 5);
•
BiFunction prend deux arguments et produit un résultat.
BiFunction<String, String, String> concatener = (chaine1, chaine2) -> chaine1 + chaine2;
String resultatConcatenation = concatener.apply("Bonjour", "Monde");
F. TOUFIK
68
Java Avancé
•
Stream
Stream
1.
Qu'est-ce que Stream ?
•
Stream est une nouvelle abstraction introduite dans Java 8 pour traiter des séquences de données de manière
fonctionnelle.
•
2.
F. TOUFIK
Il permet des opérations de traitement de données de manière déclarative.
Caractéristiques de Stream
•
Stateless : Les opérations sur un Stream n'affectent pas l'état des éléments sous-jacents.
•
Composable : Les opérations peuvent être combinées pour former des pipelines.
•
Lazy : Les opérations ne sont effectuées que lorsqu'un résultat est nécessaire.
69
Java Avancé
•
1.
Stream
Utilisation de Stream
Création d'un Stream
•
Les Stream peuvent être créés à partir de différentes sources (collections, tableaux, générateurs, etc.).
List<String> noms = Arrays.asList("Ahmed", "Khadija", "Amine");
Stream<String> streamNoms = noms.stream();
2.
Opérations Intermédiaires
•
Les opérations intermédiaires sont des transformations qui produisent un nouveau Stream.
Stream<String> nomsEnMajuscules = streamNoms.map(String::toUpperCase);
3.
Opérations Terminales
•
Les opérations terminales produisent un résultat ou un effet final.
long nombreDeMajuscules = nomsEnMajuscules.count();
F. TOUFIK
70
Java Avancé
•
1.
Stream
Opération courantes sur Stream
Filtrage avec filter
•
filter permet de sélectionner les éléments en fonction d'une condition.
List<Integer> nombresPairs = nombres.stream()
.filter(nombre -> nombre % 2 == 0)
.collect(Collectors.toList());
2.
Transformation avec map
•
map permet de transformer chaque élément du Stream.
List<Integer> longueursNoms = noms.stream()
.map(String::length)
.collect(Collectors.toList());
3.
Réduction avec reduce
•
reduce combine les éléments pour produire un résultat unique.
Optional<String> concatenation = noms.stream()
.reduce((nom1, nom2) -> nom1 + ", " + nom2);
F. TOUFIK
71
Java Avancé
•
•
DateTime
DateTime API
•
Java DateTime API a été introduite dans Java 8 pour simplifier la manipulation des dates et heures.
•
Elle remplace les anciennes classes telles que Date et Calendar par un modèle plus moderne et flexible.
Principales classes
•
LocalDate : Représente une date (année, mois, jour) sans information sur le fuseau horaire.
LocalDate date = LocalDate.now();
•
LocalTime : Représente une heure du jour sans information sur la date et le fuseau horaire.
LocalTime time = LocalTime.now();
•
LocalDateTime : Représente une combinaison de date et d'heure sans information sur le fuseau horaire.
LocalDateTime dateTime = LocalDateTime.now();
•
ZonedDateTime: Représente une date et une heure avec des informations sur le fuseau horaire.
ZonedDateTime zonedDateTime = ZonedDateTime.now();
F. TOUFIK
72
Java Avancé
DateTime
•
Manipulation des dates et heures
•
Exemples :
•
LocalDate : Ajout de jours.
LocalDate newDate = date.plusDays(7);
• LocalTime : Ajout d’heures.
LocalTime newTime = time.plusHours(2);
• LocalDateTime : Ajout de mois.
LocalDateTime newDateTime = dateTime.plusMonths(3);
F. TOUFIK
73
Java Avancé
•
DateTime
Formatage, Parsing & Comparaison de dates
•
Formatage d’une date:
LocalDateTime dateTime = LocalDateTime.now();
String formattedDate = dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
• Parsing d'une date à partir d'une chaîne :
LocalDateTime parsedDateTime = LocalDateTime.parse("2024-01-27 15:30:00",
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
• Comparaison
Comparaison de dates avec isBefore, isAfter, isEqual :
boolean isAfter = dateTime1.isAfter(dateTime2);
F. TOUFIK
74
Java Avancé
JUnit
• Les Tests Unitaires
•
Définition
•
Un test unitaire est une procédure automatisée destinée à vérifier qu'une partie spécifique d'un programme
fonctionne correctement.
•
Les tests unitaires se concentrent sur des parties isolées du code, généralement des méthodes ou des fonctions,
appelées "unités".
•
F. TOUFIK
Objectifs
•
Validation du Code : S'assurer que chaque composant individuel du logiciel fonctionne comme prévu.
•
Détection Précoce des Erreurs : Identifier les erreurs le plus tôt possible dans le cycle de développement.
75
Java Avancé
•
JUnit
Junit
•
•
•
JUnit est un framework de test unitaire pour Java.
Il permet de créer, exécuter et automatiser les tests pour garantir la qualité du code.
Annotations principales
•
•
@Test : Annotation pour définir une méthode de test.
@Before & @After : Annotations pour définir des méthodes qui s'exécutent avant et après chaque test
respectivement.
•
@BeforeClass & @AfterClass : Annotations pour définir des méthodes qui s'exécutent avant et après l'exécution de la
classe de test respectivement.
• Assertions
•
JUnit fournit un ensemble d'assertions pour vérifier les résultats des tests comme :
•
F. TOUFIK
assertTrue, assertFalse, assertEquals, …
76
Java Avancé
JUnit
public class ExempleTest {
// Variable à utiliser dans les tests
private static int valeur;
@BeforeClass
public static void setUpClass() {
System.out.println("Mise en place des ressources globales pour
la classe");
valeur = 42;
}
@AfterClass
public static void tearDownClass() {
System.out.println("Libération des ressources globales pour la
classe");
}
@After
public void tearDown() {
System.out.println("Libération des ressources
après chaque test");
// Autres nettoyages si nécessaire
}
@Before
public void setUp() {
System.out.println("Mise en place des ressources avant chaque
test");
// Autres initialisations si nécessaire
}
@Test
public void testAjout() {
System.out.println("Test d'ajout");
int resultat = valeur + 10;
Assert.assertEquals(52, resultat);
}
@Test
public void testSoustraction() {
System.out.println("Test de soustraction");
int resultat = valeur - 5;
Assert.assertEquals(37, resultat);
}
}
F. TOUFIK
77
Download