Académique Documents
Professionnel Documents
Culture Documents
avancée
MPSSI1 2023/2024
Partie 1
2
Qu'est-ce que Java ?
3
Bref historique
1990 : Développé chez SUN Microsystems par
James Gosling, Mike Sheridan et Patrick Naughton
nommé Oak puis appelé Java (café en argot américain).
1995 : Lancé HotJava browser développé en Java
Janv. 96 : JDK 1.0
Fév. 97 : JDK 1.1
…
2009 : SUN a été rachetée par la société Oracle
…
Sep. 2021 : JDK 17 (version LTS)
Sep. 2023 : JDK 21
4
Un exemple de code
class Bonjour {
public static void main (String args[]) {
System.out.println("Bonjour ISIMG!");
}
}
5
Notions dans le monde objets
Objets & Classe Programmation Objet = Polymorphisme
6
Programmation structurée vs.
Programmation objet
Programmation structurée Programmation objet
traitements
7
Principe des modèles objets
Les modèles à objets ont été créé pour
modéliser le monde réel
Toute entité du monde réel est un objet
Tout objet représente une entité du monde
réel
un exemple : Article
Article
8
Objet
objet
=
données + opérations sur ces données (méthodes)
=
variable de "type abstrait" (non scalaire)
=
entité du domaine du problème
Exemple d'objets : des voitures
objet R21_de_mon_chef objet ma_Clio
genre : Renault genre : Renault
plaque : 2245 TUN 115 plaque : 4357 TUN 93
NbPlaces : 5 NbPlaces : 4
propriétaire: chef propriétaire: Moi
s_arreter() s_arreter()
avancer() avancer()
fin objet fin objet
9
Programme objet
Un programme = une société d'entités
Son exécution : les entités s'entraident pour résoudre le
problème final en s'envoyant des messages.
une entité = un objet qui prend en compte sa propre
gestion (objet responsable)
un message = est traduit en appel de méthode
10
Principe d’encapsulation
Encapsulation
=
regroupement de code et de données
masquage d'information au monde extérieur
Un objet est composé de 2 parties :
partie publique : opérations qu'on peut faire dessus
partie privée : partie interne (intime) = données sensibles
de l'objet (les attributs et les autres méthodes)
Les utilisateurs de l'objet ne voient (c.-à-d. ne peuvent
utiliser et ceci est contrôlé par le compilateur) que la
partie publique
Objectifs :
Seul l’objet peut modifier ses propre attributs
Masquer les détails de l’implémentation
11
Principe d’encapsulation
Objectif :
comportement état
Interface = partie
publique
12
Classe
classe
=
modèle décrivant le contenu et le comportement des futurs objets
de la classe
=
ensemble d'objets
13
Résumé :classe & objet
classe & objet, méthode et message :
Un exemplaire particulier d'une classe s'appelle une
instance de la classe ou un objet de cette classe :
objet = instance de classe
Une classe est un agrégat d'attributs et de méthodes : les
membres
En première approche:
les objets sont à la programmation objet ce que sont les
variables à la programmation structurée
Les classes sont à la programmation objet ce que les
types sont à la programmation structurée
programmation procédurale Variable type
14
Déclaration d’une classe
Format classique d’un fichier java: import: on le voit
plus loin dans le
import classes; cours
class NomClasse
{ main() est optionnel: il permet
Attribut(s) de la classe; d’executer la classe via la JVM:
>java NomClasse
Méthode(s) de la classe;
15
Classes et objets : exemple
Propriété / méthode
class Cercle { référence d’un objet :Cercle c;
double x, y; créer un objet: l'opérateur new
double r; constructeur
Cercle(double R) {
r = R;
}
double aire() {
return 3.14159 * r * r;
}
}
class MonPremierProgramme
{
public static void main(String[] args) {
Cercle c; // c est une référence sur un objet Cercle, pas un objet
c = new Cercle(5.0); // c référence maintenant un objet alloué en mémoire
16
Syntaxe : classes & objets
CLASSE OBJET
tout est défini à l'intérieur de En Java il faut construire
classe : il n'y a rien de global explicitement les objets ( new )
Les méthodes sont définies directement Par la suite les objets construits
dans la classe
seront repérés et accessibles
les constantes aussi grâce à leur référence initialisée
On définit les classes par : au moment de la construction de
class nomClasse { l'objet.
type_donnees données
définition des méthodes On a donc :
Voiture ma_Clio;
}
déclaration d'une référence.
par exemple :
class Voiture { Puis
String genre; ma_Clio = new Voiture();
String immatriculation;
int NbPlaces; Ayant une référence ma_Clio
String propriétaire; initialisée, on l'utilise alors pour
void s_arreter(){ ... } lancer toute méthode sur l'objet
void avancer(float nbmetres) (i.e. pour envoyer tout message à
{ ... } l'objet) par :
} ma_Clio.avancer(4.5);
17
Constructeur
Pour initialiser un objet, on utilise une méthode "spéciale" appelée
constructeur (même nom que la classe sans valeur de retour)
elle est appelé automatiquement au moment du new
class Cercle {
double x, y, r;
Cercle(double X, double Y, double R) {
x = X; y = Y; r = R;
}
Cercle(Cercle c) {
x = c.x; y=c.y; r=c.r;
}
Cercle() {
x=y=r=0;
}
}
Toute classe possède un constructeur par défaut, implicite.
Celui-ci peut être redéfini (ici le dernier constructeur)
Une classe peut avoir plusieurs constructeurs qui diffèrent par le
nombre et/ou la nature de leurs paramètres (surcharge)
18
La surcharge
Dans une classe, plusieurs méthodes ou constructeurs
peuvent coexister avec un même nom si elles ont des
signatures différentes.
La signature est constituée de :
nombre de ces paramètres
type de chacun de ces paramètres.
Exemple :
class Cercle {
double x, y, r;
void Initialiser(double X, double Y, double R) {
x = X; y = Y; r = R;
}
void Initialiser(Cercle c) {
x = c.x; y=c.y; r=c.r;
}
void Initialiser() {
Initialiser(0.0, 0.0, 0.0);
NOTE: “Initialiser” peut etre
} remplacé par le constructeur
}
19
Destruction d'un objet
La destruction des objets est prise en charge par
le garbage collector (GC).
Le GC détruit les objets pour lesquels il n'existe
plus de référence.
Les destructions sont asynchrones (le GC est
géré dans un thread de basse priorité).
Aucune garantie n'est apportée quant à la
destruction d'un objet.
Si l'objet possède la méthode finalize(),
dépréciée depuis Java 9, celle-ci est appelée
lorsque l'objet est détruit.
20
Héritage (1)
Héritage
=
construire une classe à partir d'une autre
=
Notion rattachée aux classes
héritage simple: héritage = dérivation
La classe dont on dérive est dite classe
de base (ou parente ou mère)
Les classes obtenues par dérivation
sont dites classes dérivées.
L'héritage permet de reprendre
intégralement tout ce qui a déjà été
fait et de pouvoir l'enrichir
(réutilisabilité)
en dérivant, on établit ainsi une
spécialisation
{ … }
}
22
Héritage (3)
Une classe ne peut hériter (extends) que d'une
seule classe à la fois.
23
Héritage (4)
class Ellipse {
double r1, r2;
Ellipse(double r1, double r2) { this.r1 = r1; this.r2 = r2;}
double aire(){return 0;}
}
class Cercle extends Ellipse {
Cercle(double r) {super(r, r);}
double getRayon() {return r1;}
}
class MonSecondProgramme
{
public static void main(String[] args) {
24
Le masquage des variables
Une classe peut définir des variables portant le
même nom que celles de ses classes ancêtres
25
Spécialisation des méthodes
On considère 2 classes liées par l'héritage.
Par exemple :
class Employee { . . . }
class Manager extends Employee { . . . }
Souvent une méthode est définie dans la classe de base, mais a besoin
d'être "affinée" dans la classe dérivée. On a par exemple :
class Employee {
long calculPrime() { return 1000; } // une prime pour un employé
}
26
Polymorphisme (1)
Le nom de la méthode calculPrime() désigne 2 codes distincts. Autrement
dit l'identificateur calculPrime représente "plusieurs formes" de code
distinct. On parle de polymorphisme.
On utilise le polymorphisme à l'aide d'une référence d'objet de classe de
base. Par exemple on écrit en Java :
Employee e = new Employee();
e.calculPrime(); // lance la méthode calculPrime() de la classe Employee
27
Polymorphisme (2)
Le gros avantage du polymorphisme est de pouvoir référencer des
objets sans connaître véritablement leur classe (mais celle d’une
classe mère), et de pouvoir par la suite, lancer le code approprié à
cet objet au moment de l'exécution du programme (et non pas à la
compilation).
On peut ainsi écrire un code comme par exemple
int calculSalaire(Employe e)
{
int salaire = e.calculSalaireDeBase();
salaire += e.calculPrime();
return salaire;
}
28
Polymorphisme (3)
Reprenons l’exemple précédent :
(1)Employee e = new Employee();
(2)e.calculPrime(); // lance la méthode calculPrime() de la classe Employee
(3)e = new Manager();
(4)e.calculPrime(); // lance la méthode calculPrime() de la classe Manager
Si e référence un Manager (ligne 3), le code (ligne 4) de la méthode e.calculPrime() de
la classe Employee ne sera pas exécuté
Le code à lancer est déterminé suivant la classe de l'objet et non
pas la classe de la référence à cet objet
Comment cela fonctionne ?
Un appel : e.calculPrime() recherche au moment de l'exécution l'objet référencé par e
A partir de cet objet, l'interpréteur cherche si la méthode calculPrime() existe dans la
classe de cet objet. Si c'est le cas, cette méthode est lancée et le processus est terminé.
Sinon, l'interpréteur refait cette recherche dans la classe de base, et ainsi de suite
Une exception est levée si une telle méthode n'est pas trouvée dans les classes parentes
En conclusion, il est fondamental de voir que pour utiliser le polymorphisme, il faut :
avoir au départ une arborescence d'héritage sur les classes en jeu
utiliser des références d'objet de la classe de base (la classe mère)
avoir (au moins) deux méthodes de même signature définies l'une dans la classe de
base, l'autre dans la classe dérivée.
29
Surcharge vs. Polymorphisme
Il ne faut pas confondre les notions de surcharge et polymorphisme
(ou liaison dynamique) qui ont finalement peu de point commun.
Voici un tableau qui résume les différences :
Surcharge Polymorphisme
30
Partie 2
31
Mot-clé static (1)
Placé devant un attribut ou une méthode
static int count = 0;
static Cercle bigger(Cercle c1, Cercle c2) {…}
32
Mot-clé static (2)
class Cercle {
static int count = 0;
int x, y, r;
Cercle(int R) {r = R; count++;}
boolean plusGrand(Cercle c) {
if (c.r > r) return false; else return true;
}
static Cercle bigger(Cercle c1, Cercle c2) {
if (c1.r > c2.r) return c1; else return c2;
}
}
public class Principale {
public static void main (String args[]) {
int n = Cercle.count;
Cercle c1 = new Cercle(10);
Cercle c2 = new Cercle(20);
n = Cercle.count;
n=Cercle.x;
n=c1.x;
boolean sup = c1.plusGrand(c2);
boolean gran = Cercle.plusGrand(c2);
Cercle c4 = Cercle.bigger(c1, c2);
n=c4.count;
Cercle.count =10;
}
}
33
Constantes: static final
Une constante est une variable static final
Exemple: static final float pi = 3.14f ;
« final » signifie que la valeur n ’est plus
modifiable
(on peut utiliser final sans static !)
Dans l’exemple précédent, ça donnerait:
class Cercle {
static int count = 0;
static final double PI = 3.14;
double x, y, r; final pour éviter par exemple
Cercle.PI = 3.14 dans le main.
...
34
Mot clef final
final : Mot clef qui s’applique à une classe, méthode ou
propriété.
Classe : final indique que la classe ne peut plus être
héritée
Méthode : final indique que la méthode ne peut pas
être redéfinie dans les classes dérivées.
Une méthode static ou private est
automatiquement final
Propriété : final indique qu’il s’agit d’une constante.
Une propriété final ne peut être affectée qu’une
seule fois.
35
Mot clef this
Le mot clef this fait référence à l’instance en cours
quand on est dans le code de la classe.
il permet de différencier les attributs d’une classe
des paramètres passées à une méthode
Exemple:
class Cercle {
double r;
Cercle(double r) {
this.r = r;
}
...
Il peut être aussi utilisé pour invoquer un constructeur
de la même classe
Exemple : Cet ligne fait appel au
public Cercle () { constructeur ci-dessus
this ( 1.0 ) ;
}
Note: les méthodes statiques ne peuvent pas accéder à this
36
Mot clef super (1)
Vous savez que grâce à l’héritage:
Une classe peut définir des attributs portant le
même nom que ceux de ses classes ancêtres
(masquage)
Une classe peut définir des méthodes portant le
même nom que celles dans sa classe mère
(redéfinition)
Le mot clef super est un préfixe qui fait référence à la
classe parente
Grace à super, une classe peut accéder aux
attributs et méthodes de sa classe mère
37
Mot clef super (2)
class A {
int x=1;
void m() {...}
}
class B extends A{
int x=2;
void m() {...}
}
class C extends B {
int a, x=3;
void m() {...}
void test() {
a = x;
a = super.x;
a = super.super.x;
a = ((A)this).x;
a = ((B)this).x;
super.m();
super.super.m();
((A)this).m();
}
}
38
Mot clef super (3)
Le mot clef super permet d’appeler le constructeur
(tous les types de constructeur) de la classe mère
public class Ellipse {
double r1, r2;
Ellipse(double r1, double r2) { this.r1 = r1; this.r2 = r2;}
}
39
Mot clef abstract
abstract : Mot clef qui s’applique à une classe ou une
méthode
une méthode est dite abstraite si on ne veut écrire que le
prototype (=la « signature ») - pas le corps
Si dans une classe, au moins une méthode est déclarée
abstract, alors la classe le devient
L’implémentation (=le corps) de la méthode s’effectue dans
les classes qui héritent de cette classe
Pour ne plus être abstraite, une classe fille doit implémenter
toutes les méthodes abstraites de la classe dont elle hérite
Si une classe est déclarée abstract, alors elle ne peut pas être
instanciée (pas de new possible)
abstract class C1 { class C2 extends C1{
abstract void toto( ); void toto( ){
void normale( ){ // corps de la méthode
// corps de la méthode }
} }
}
40
Mots clefs
Une méthode peut :
Appartenir à la classe (static)
Appartenir aux instances (sans static)
Ne pas avoir d’implémentation (abstract)
Bloquer toute redéfinition (final)
41
Partie 3
Packages, Visibilités
42
Les packages
Un package regroupe un ensemble de classes sous un
même espace de noms
L'intérêt est de regrouper les classes par thème, lien
logique, dépendance…
un package équivaut à un répertoire contenant des
fichiers classes
un package peut contenir des sous-packages
pour utiliser des classes contenues dans un package, il
faut soit :
utiliser leur nom long package.souspackage.classe
utiliser la clause import (avec ou sans « * »)
Les API de java sont organisées en packages (ex:
java.lang, java.io, java.net …)
43
Packages personnalisés (1)
L'instruction package indique à quel package appartient
la ou les classe(s) du fichier.
package doit être la première instruction du fichier
source
Par défaut (si pas d'instruction package dans le fichier)
une classe appartient au package anonyme.
Exemple :
package forme;
class Cercle {
double x, y, r;
void Cercle(double x, double y, double r) {
this.x = x; this.y = y; this.r = r;
}
...
44
Packages personnalisés (2)
L'arborescence des répertoires contenant les classes doit être
identique à l'arborescence des packages
les noms des packages/répertoires sont case sensitifs
par defaut le package anonyme est le repertoire courant
Une classe Cercle appartenant au package Forme.2D doit se
trouver dans le fichier Forme/2D/Cercle.class
sources packages répertoires
Package Forme;
... Forme
Package Forme.2D;
... 2D
Package Forme.3D; 3D
...
45
Encapsulation & Visibilité (1)
Mots clés utilisable pour gérer les droits d’accès pour un
membre (variable ou méthode) :
public
visible par toutes les autres méthodes à l’intérieur
de l’objet ou à l’extérieur.
protected
visible uniquement dans sa classe ou sous classe (et
dans le package)
private
private sera visible uniquement dans sa classe.
<sans>
visible uniquement dans le package en cours -
Equivalent à public mais pour le package
46
Encapsulation & Visibilité (2)
A B C D
Accessible par c2 o o o -
Accessible par c3 o o o -
Accessible par c4 o o - -
Accessible par c5 o - - -
47
Partie 4
Interface
48
Héritage et interface (1)
Une interface est introduite par le mot clé « interface »,
et se comporte comme une classe dont les méthodes
sont par défaut publiques et abstraites et dont tous les
attributs sont final.
Les mots clés final, abstract, public sont facultatifs dans
la définition d’une interface.
Une interface est un moyen de préciser les services
qu'une classe peut rendre. C’est un modèle
d'implémentation. Elle est inutilisable en elle-même.
Depuis Java 8, une interface peut aussi contenir des
méthodes par défaut et/ou des méthodes statiques.
Une méthode par défaut consiste à spécifier une signature
de méthode avec une implémentation par défaut.
Depuis Java 9, une interface peut aussi contenir des
méthodes privées et/ou des méthodes statiques
privées.
49
Héritage et interface (2)
Héritage multiple est interdit entre classes.
Une interface peut hériter (extends) de plusieurs
interfaces.
Une classe peut implémenter (implements) une ou
plusieurs interfaces tout en héritant (extends) d'une
classe.
Une interface fonctionnelle est une interface qui ne
contient qu’une seule méthode abstraite. Elle ne peut
avoir qu’une seule fonctionnalité à exposer.
Une interface fonctionnelle peut contenir des méthodes par
défaut et statiques qui ont une implémentation, en plus de la
méthode unique abstraite.
Java fournit une annotation @FunctionalInterface, qui est
utilisée pour déclarer une interface fonctionnelle.
50
Héritage et interface (3)
interface MyInterface {
default void defaultMethod(){
System.out.println("Default");
}
static void staticMethod(){
System.out.println("Static");
}
}
public class MyClass implements MyInterface {
public void defaultMethod(){
System.out.println("Replace Default");
}
public static void main(String[] args) {
new MyClass().defaultMethod();
MyInterface.staticMethod();
}
static void staticMethod(){
System.out.println("another static...");
}
}
51
Héritage et interface (4)
Une expression lambda est une fonction qui peut être
créée sans appartenir à aucune classe. Elle peut être
transmise comme s’il s’agissait d’un objet et exécutée à
la demande.
L’expression lambda fournit l’implémentation d’une
interface fonctionnelle.
Une expression Lambda est en quelque sorte la redéfinition de
l’unique méthode abstraite d'une interface fonctionnelle, sans
avoir à faire une classe.
Syntaxe d’une expression lambda :
(liste de paramètres) -> {corps de la fonction}
<liste de paramètres> : indique les paramètres en entrée de l'unique
méthode abstraite de l'interface fonctionnelle. Ils seront saisis entre () et
il n'est pas obligatoire d'indiquer leurs types ;
-> : c'est le marqueur de l'expression Lambda. Il sépare la liste des
paramètres du corps de la fonction ;
<corps de la fonction> : entre {} ou pas, s'il n'y a qu'une seule
instruction.
52
Héritage et interface (5)
@FunctionalInterface
interface Square {
int calculate(int x);
}
class TestSquare {
public static void main(String args[]){
int a = 5;
// expression lambda pour définir la méthode calculate
//affecter l'expression lambda à l'instance de l'interface fonctionnelle
Square s = (int x) -> x * x;
// return et le paramètre passé doivent être de même type que le prototype
int res = s.calculate(a);
System.out.println(res);
}
}
53
Héritage et interface (6)
class A{
public String f (D obj ) { return "A et D"; }
public String f (A obj ) { return "A et A"; }
}
class B extends A{
public String f (B obj ) { return "B et B"; }
public String f (A obj ) { return "B et A"; }
}
class C extends B{ }
class D extends B{ }
54
Héritage et interface (7)
public class Test {
public static void main (String[ ] args) {
A a1 = new A( ) ;
A a2 = new B( ) ; B b = new B( ) ;
C c = new C( ) ; D d = new D( ) ;
System.out.println (a1.f (b));
System.out.println (a1.f (c));
System.out.println (a1.f (d));
System.out.println (b.f (b));
System.out.println (b.f (c));
System.out.println (b.f (d));
System.out.println (a2.f (b));
System.out.println (a2.f (c));
System.out.println (a2.f (d)) ;
}
}
55
Héritage et interface (8)
class A {
public String f(D obj) { return "A et D"; }
public String f(B obj) { return "A et B"; }
public String f(A obj) { return "A et A"; } }
class B extends A {
public String f(C obj) { return "B et C"; }
public String f(A obj) { return "B et A"; } }
interface X{
default String f(A obj) { return "X et A"; } }
interface Y extends X{
default String f(A obj) { return "Y et A"; } }
class C extends B implements X {
public String f(A obj) { return "C et A"; } }
class D extends C implements Y{
public String f(A obj) { return Y.super.f(obj); } }
56
Héritage et interface (9)
public class Test1 {
public static void main ( String[ ] args) {
A a1 = new A();
A a2 = new B(); B b = new B();
C c = new C();
D d = new D(); X c1 = new D();
System.out.println(c1 instanceof C);
System.out.println(c1 instanceof A);
System.out.println(c1 instanceof Y);
System.out.println(a1.f(new B()));
System.out.println(a1.f(a2));
System.out.println(a2.f(a2));
System.out.println(c.f(b));
System.out.println(d.f(c));
System.out.println(d.f(a2));
B b1= (B)a2;
B b2=(B)a1;
}}
57
Partie 5
Exceptions
58
Exceptions (1)
Le mécanisme des exceptions permet de gérer de façon
élégante les erreurs pouvant survenir à l’exécution. Elles
présentent trois avantages :
Obliger les programmeurs à gérer les erreurs.
Séparer le code de traitement des erreurs du reste du code.
Rattraper les erreurs en cours d’exécution.
Lorsqu’une séquence d’instructions est susceptible de
provoquer une erreur, on la place dans un bloc try.
Comme ci-dessous :
try
{ /*
blocs d’instructions
*/
}
59
Exceptions (2)
On place juste après le bloc try un bloc catch qui permet
de traiter l’erreur :
try
{
/*
blocs d’instructions
*/
}
catch ( nomErreur e )
{
/*
Traitement de l’erreur
*/
}
60
Exceptions (3)
Une exception est une erreur pouvant être rattrapée en
cours d’exécution.
Cela signifie que si une erreur survient, une exception est
levée, le code du try est interrompu et le code contenu
dans le catch est exécuté. Par exemple, dans le code
suivant, l’indice i est incrémenté jusqu’à ce que cet indice
dépasse la taille du tableau. Dans ce cas, l’exception
ArrayIndexOutOfBoundsException est levée et le code
correspondant à cette exception dans le catch est exécuté.
try {
int i = 0 ;
int[] tab =new int[10];
while ( true )
System.out.println(tab[i++]);
}
catch ( ArrayIndexOutOfBoundsException e ){
System.out.println("Une exception est survenue") ; }
61
Exceptions (4)
Si vous rédigez une méthode susceptible de lever une
exception, vous devez la déclarer en ajoutant à son
entête l’expression throws <listeExceptions>.
Par exemple :
62
Exceptions (5)
try
{
bourreTableau();
}
catch ( ArrayIndexOutOfBoundsException e )
{
System.out.println("Il fallait s’y attendre");
}
63
Exceptions (6)
Propager une exception, c’est laisser le sous-
programme appelant la traiter mais il est possible lorsque
l’on invoque un sous-programme levant cette exception
de la propager encore. Par exemple,
64
Exceptions (7)
Une exception est tout simplement une classe héritant
de la classe Exception.
class MonException extends Exception
{
public MonException(){
System.out.println("Constructeur");
}
public String toString(){
return "Méthode d’affichage d’un objet !" ;
}
}
On lève une exception en utilisant la syntaxe :
throw new <nomexception>(<parametres>).
L’instanciation de l’exception se fait donc en même
temps que sa levée. Par exemple :
65
Exceptions (8)
try
{
/*
. . . . . .
*/
throw new MonException() ;
/*
. . . . . .
*/
}
catch ( MonException e )
{
System.out.println(e);
}
66
Exceptions (9)
Il se peut qu’une même instruction (ou suite
d’instructions) soit susceptible de lever des exceptions
différentes, il est possible dans ce cas de placer
plusieurs catch à la suite du même try.
try
{
bourreTableau(); Notez bien que
} comme toute
catch ( ArrayIndexOutOfBoundException e ) exception hérite de
Exception, le
{
deuxième catch sera
System.out.println("Il fallait s’y attendre");
exécuté quelle que
}
soit l’exception
catch ( Exception e ) levée (sauf si bien
{ entendu le premier
System.out.println(e); catch est exécuté).
}
67
Exceptions (10)
Il est quelquefois nécessaire qu’une section de code
s’exécute quoi qu’il advienne (par exemple fermer un
fichier). On place dans ce cas une section finally.
try
{
// . . . . . .
}
catch ( /* . . . */ )
{
// . . . . . .
}
finally
{
// . . . . . .
}
68
Exceptions (11)
class Except extends Exception { }
public class TestFinally{
public static void f(int n){ // pas de throws
try
{ if (n!=1)
throw new Except();
}
catch (Except e)
{ System.out.println(" catch dans f - n = " + n );
return ; }
finally
{ System.out.println(" dans finally - n = " + n ); }
}
public static void main (String args[])
{ f(1); f(2); }
}
69
Traitement des exceptions
Le bloc try est exécuté jusqu'à ce qu'il se termine avec
succès ou bien qu'une exception soit levée.
Dans ce dernier cas, les clauses catch sont examinées
l'une après l'autre dans le but d'en trouver une qui traite
cette classe d’exceptions (ou une superclasse).
Les clauses catch doivent donc traiter les exceptions
de la plus spécifique à la plus générale.
La présence d'une clause catch qui intercepte une classe
d'exceptions avant une clause qui intercepte une sous-
classe d'exceptions déclenche une erreur de compilation.
Si une clause catch convenant à cette exception a été
trouvée et le bloc est exécuté, l'exécution du
programme reprend son cours.
70
Arbre des exceptions
Throwable
Récupérables
le programme a la possibilité
d'attraper ces exceptions
Exception Error
Les exceptions non récupérables
construites par RuntimeException erreurs "systèmes"
l'utilisateur étendent la (plus de mémoire, ...)
ArrayIndexOutOfBoundsException
classe Exception
ArithmeticException Il est recommandé de
Vos Exceptions … ne pas les corriger.
… Exceptions prédéfinies
71
Instruction « try-with-resources »
(1/3)
Des ressources (comme des fichiers, des flux, des
connexions, etc.) doivent être fermées explicitement par
le développeur pour libérer les ressources sous-jacentes
qu'elles utilisent.
Utiliser un bloc try / finally pour garantir leur fermeture.
L'instruction « try-with-resources », apparue dans
Java 7, permet de définir une ressource qui sera
automatiquement fermée à la fin de l'exécution du bloc
de code de l'instruction.
Tous les objets qui implémentent l'interface
java.lang.AutoCloseable peuvent être utilisés dans une
instruction de type « try-with-resources ».
InputStream, OutputStream, Reader, Writer (java.io),
Connection, Statement, ResultSet (java.sql) …
72
Instruction « try-with-resources »
(2/3)
L’interface java.lang.AutoCloseable ne définit qu’une
seule méthode abstraite : la méthode close
c'est ce qui garantira à l'instruction « try-with-resources »
qu'elle pourra forcer la fermeture de la ressource.
Si cette instruction est utilisée sur un type n'implémentant pas
cette interface, une erreur de compilation sera produite.
Avec Java 7, les ressources à libérer sont positionnées
entre parenthèses et directement à la suite du mot
clé try.
73
Instruction « try-with-resources »
(3/3)
// Deux ressources automatiquement gérées
try ( FileInputStream fis = new FileInputStream( "Fich1.txt" );
FileOutputStream fos = new FileOutputStream( “Fich2.txt" ) ) {
// Ici on manipule les deux fichiers
} // Appel aux méthodes close automatique
74