chapitre 2 objets et java - docs.drlazor.be
TRANSCRIPT
www.unamur.be
Chapitre2ObjetsetJava
VoirLiskov&Guttag,ch.2« UnderstandingObjects inJava »,pp15-37
62
www.unamur.be
Lesobjets
• Objet(sensrestreint)— « morceau »deprogrammeencoursd’exécution quipossède
§ unétat contenantdesdonnéesmanipuléesparleprogramme
§ uncomportement faitd'opérations (appeléesméthodes)
— On interagitavecunobjeteninvoquantsesméthodes§ « On »=lecodeappelant(unobjet,uneprocédureouleprogramme
principal)
— Lesméthodesd’unobjetpermettent(entreautres)d’accéderàsonétat:lire/consulter (Read,leRdeCRUD)ouécrire/modifier (Update,leUdeCRUD)
63
www.unamur.be
Exemple:
• Ceprogrammedoitmaintenirdesdonnéessur— lesarticlesenvente
§ leurtitre,leur(s)auteur(s)/artiste(s),leurdescriptif,...§ lenombred’exemplairesdisponiblesenstock§ leurprix§ ...
— lesclients§ leurnom§ leurscoordonnées§ ...
— lescommandes§ leslivrescommandésetenquellequantité§ leclientquiapassélacommande§ ...
— etc...
64
www.unamur.be
Exemple:
• Siceprogrammeest« orienté-objet»,lorsdesonexécution,ontrouveradanscelui-ciunemultituded’objetsdechaquetype(Article,Client,Commande,...)
65
Patrick HeymansRue Grandgagnage, 21
B-5000 NamurTél : 32 (0)81 725275 Commande 749674
x 1
x 1
x 1
Franz Ferdinand, "Franz Ferdinand »13,99 € , 418 ex. dispo
Interpol, « Antics »13,99 € , 283 ex. dispo
Manu Larcenet,« Le combat ordinaire,
tome 1 »,ISBN 2205054252
11,99 € , 58 ex. dispoJ-C Vandamme... Commande 25488
x 1
www.unamur.be
Exemple:Invocationdeméthode
66
Commande749674
donneNumero()
749674...
www.unamur.be
Exemple:Invocationdeméthode
• Lecture
67
donnePrix()
11,99...
Manu Larcenet,« Le combat ordinaire,
tome 1 »,ISBN 2205054252
11,99 € , 58 ex. dispo
www.unamur.be
Exemple:Invocationdeméthode
• Ecriture
68
changePrix(12,49)
...
Manu Larcenet,« Le combat ordinaire,
tome 1 »,ISBN 2205054252
12,49 € , 58 ex. dispo
www.unamur.be
Exemple:Invocationdeméthodesenchaîne
• Généralement,uneinvocationdeméthodedéclencheunemultituded’appels...
• ...maisquel’appelantn’apasàconnaître(délégationderesponsabilité)
• Analogueàl’envoidefleursàBritney!
69
Commande749674
calculeMontant()
48,36...
donnePrix() 13,99
calculeFraisDEnvoi()
8,39
www.unamur.be
Vuedebasniveau
• Traditionnellement, l’exécution d’un programme est vue commececi : un processeur exécute une suite d’instructions machine quiconsultentet modifient les éléments d’unemémoire
70
i:12
j:34
x:1,234
a[0]:5
a[1]:6
a[2]:7
www.unamur.be
Vueorientée-objet• Vuedehautniveau selonlaquellel’exécutiond’unprogrammeestessentiel-
lement composéed’interactionsentreobjets• Les objets représentent (= maintiennent des informations sur) souvent des
entités du monde réel (personnes, choses, concepts) issues du domained’applicationdu programme
71
Commande749674
calculeMontant()
48,36...
donnePrix()
8,39
calculeFraisDEnvoi()
13,99
www.unamur.be
DiagrammedeséquenceUn« boutd’exécution »deprogrammeestsouventillustréparundiagrammedeséquence
72
NB: ces notations graphiques n’apparaissent pas dans le livre de Liskov et Guttag
www.unamur.be
L’orienté-objet(OO)
• ProgrammeOO=programmepenséselonla vueOO
• ConceptionetProgrammationOO=résoudreunproblèmeparlebiaisd’unprogrammeOO
(i.e.penséOO)§ concevoir→ structurer(viadécomposition etabstraction)§ programmer→ écrirelecode
• Langage(deprogrammation)OO=langagepossédantdesmécanismesquifacilitent laprogrammationOO
§ onpeutdévelopper non-OOdansunlangageOO§ onpeutdévelopper OOdansunlangagenon-OO(maisc’estplus faciledans
unlangageOO!)
73
www.unamur.be
Java
• Java estunlangagedeprogrammationOO— nonOO:C,Pascal,Lisp,Prolog,Ada,...
— OO:C++,C#,Eiffel,Smalltalk,Simula,Python,PHP,...+extensionsOOdelangagesnonOO
• InfluencéparleslangagesOOetdeslangagesnonOO— Esprit:Lisp,Simula67,CLU,SmallTalk,...
— Forme(syntaxe):C,C++
• Ainfluencéd’autreslangages— Python,C#
74
www.unamur.be
Etvousdanstoutça
• Aufildececours,nousallons— comprendreetmettreenpratiquelesprincipesdebase delaconception
etdelaprogrammationOO— comprendreetutiliserlesmécanismesqueJavametauservicedeces
principes
• Objectif:vousfairedevenirdebonconcepteurs/programmeursOO— quimaîtrisentlesprincipesdel’OO etpeuventlesappliquerdansde
nombreuxlangages
• Pasunobjectif:fairedevousdeshackersJava— eneffet,leslangagespassent,maislesprincipesrestent...
75
www.unamur.be
Classes
• LesprogrammesJavasontcomposésdedéfinitionsdeclasses (etd’interfaces)
class Client {......
}
class Article {......
}
class Commande {......
}
76
Classe = élément d’un programmeObjet = élément d’une exécution
A tout moment de l’exécution,chaque classe du programme peutavoir plusieurs objets (instances)
www.unamur.be
Diagrammesdeclasses• Onreprésenteragraphiquementlesclassesd’unprogrammedansdes
DiagrammesdeClassesUML(ClassDiagrams)
NB:cesnotationsgraphiquesn’apparaissentpasdanslelivredeLiskov etGuttag
77
www.unamur.be
ClassesUtilités
Uneclasseadeuxutilitéspossibles
• définirdescollectionsdeprocédures/méthodes/opérations
(abstractionprocédurale)
• définirdestypesdedonnées
(abstractiondedonnées)
78
www.unamur.be
Utilisationdesclassespourl’abstractionprocédurale
Exemple1:laclasseNum quirassemblediversesméthodesdecalculnumérique
class Num {public static int gcd(int n, int d) {// pré : n>0, d>0// post : retourne le pgcd de n et d while (n != d)
if (n > d) n = n - d; else d = d - n;return n;
}
public static boolean isPrime(int p) {// pré : p>0// post : retourne true si p est premier,// retourne false sinon...
}...}
79
www.unamur.be
Diagrammedeclasse
• Lesméthodesstatic sontsoulignées• Lesméthodespublic (visiblesdesautresclasses)sontprécédéesd’un+
80
+gcd(n:int, d:int) : int+isPrime(p:int) : boolean
Num
www.unamur.be
Utilisationdesclassespourl’abstractionprocédurale
Desexemplesd’appelsàcesméthodespourraientêtre:int x = Num.gcd(15,6);if (Num.isPrime(y)) ...
Lenomdelaméthodeappeléeestprécédédunomdelaclassedanslaquelleelleestdéfiniesuivid’un.(point)
81
www.unamur.be
Utilisationdesclassespourl’abstractionprocédurale
Exemple2:laclasseArrays quirassemblediversesméthodesdemanipulationdetableauxd'entiers
class Arrays {public static void sort(int[] a) {// post : a est trié en ordre croissant
...}
public static int search(int[] a, int el) {// post : retourne -1 si el n’apparaît pas dans a;// sinon retourne i tq a[i]=el et qu’il n’y a pas de j<i tq a[j]=el
...}
...}
• int[] designe untableaud’entiersdelongueurindéterminée• L’absencedevaleurderetours’indiqueparle« type »void
82
www.unamur.be
Diagrammedeclasse
83
+sort(a:int[])+search(a:int[], el:int) : int
Arrays
www.unamur.be
Utilisationdesclassespourl’abstractionprocédurale
• Exemplesd’appels:
int[] monTableau;// initialisation de monTableau...Arrays.sort(monTableau);int i = Arrays.search(monTableau,3);
84
www.unamur.be
Utilisationdesclassespourl’abstractiondedonnées
Exemple1:laclasseMultiSet
class MultiSet {public void insert(int e) {
...}public void delete(int e) {
...}public int size() {
...}
public void union(Multiset m) {...
}...}
MultiSet devientunnouveautypededonnéespouvantêtreutilisédansleprogramme
85
www.unamur.be
Utilisationdesclassespourl’abstractiondedonnées
• Attention— Pasdestatic danslesdéclarationsdeméthodesdetypesde
données
— PasdeMultiSet enparamètresnientypederetouralorsquelesopérationsdel’ADT(voirp.40)enavaient.Pourquoi?
86
www.unamur.be
Utilisationdesclassespourl’abstractiondedonnées
Exemplesd’appels:
MultiSet m = ...; // initialisation dem...m.insert(9);...m.delete(9);...MultiSet n = ...; // initialisation de n...m.union(n);
87
appels sur une instanceet pas sur une classe
www.unamur.be
Diagrammedeclasse
• Lesméthodesnonstaticnesontpassoulignées
88
+insert(e:int)+delete(e:int)+size() : int+union(m:MultiSet)...
MultiSet
www.unamur.be
Utilisationdesclassespourl’abstractiondedonnées
• Exemple2:laclasseCommande deAmazon.com
class Commande{public float calculeMontant() {
...}private float calculeFraisDEnvoi() {
...}
...}
• Commande devientunnouveautypededonnéespouvantêtreutilisédansleprogramme
• IdempourClient,Article,...• Lesméthodesinvisiblespourlesautresclassessontprécédéesde
private• Uneméthodeprivate (privée)estditeencapsulée danslaclasse
89
www.unamur.be
Diagrammedeclasse
• Lesméthodesprivate sontprécédéesd’un-
90
+calculeTotal() : float-calculeFraisDEnvoi() : float
Commande
www.unamur.be
Encapsulation
• Lestypesabstraits (classesd’abstractiondedonnées)sontdotés
— d’une interface spécifiantlesméthodesquipeuventêtreexécutéesparuneinstancedutypeetquireprésententsesresponsabilités
— d’une implémentation précisant
§ lesstructuresdedonnées (quiencodentl’étatd’uneinstance)
§ lecorpsdesméthodes
§ desméthodesauxiliaires
• L’abstractiondedonnéesestuneforme d’encapsulation :
— seulel’interface d’unobjetestaccessible depuissonenvironnement
— l’implémentation estcachée
91
www.unamur.be
Encapsulation
• Exemple:letypePile
92
interface(visible aux
autres classes)
implémentation(cachée aux
autres classes)
appel deméthode
(indépendant deson implémentation !)
boolean isEmpty()
structure internede la pile, soit:• tableau• liste chaînée•...
www.unamur.be
PrincipedeParnas
• « Ladéfinitiond’uneclassedoitfourniràl’environnementtouteslesinformationsnécessairespourmanipulercorrectementuneinstancedelaclasse,etriend’autre. »
• « L’implémentationd’uneméthodedoitsebasersurtouteslesinformationsnécessairesàl’accomplissementdesatâche,etsurriend’autre »
• Quellessontcesinformations?
93
www.unamur.be
Visibilité
• Dansladéfinitiond’uneclasse,ladistinctionentreinterfaceetimplémentations’exprimeparunmarqueurdevisibilité associéauxéléments,i.e.lesméthodes(etvariablesmembres)delaclasse:— unélémentpublic (noté+)estrenduaccessibleàtoutlecodedu
programme
— unélémentprivate (noté-)n’estaccessiblequeparlecodedelaclasseelle-même
• NB:Ilyad’autresformesdevisibilitéplusélaborées(voirplusloin)
94
www.unamur.be
Packagesetvisibilité
• Lesclassessontregroupéesenpackages (paquetages)• Exemple
95
...
...
www.unamur.be
Packagesetvisibilité
• Lespackagessonttoutd’abordunmécanismed’encapsulation— lesclasses,toutcommelesméthodes,ontunevisibilité— seuleslesclassesdéclaréespublic (notée+)peuventêtreutiliséespar
ducodesetrouvantdansd’autrespackages— lesclassesquine sontpas déclaréespublic sontutilisablesuniquement
parlecodedupackage(pardéfaut)
• Syntaxe(simplifiée)desdéclarationsdeclasses[package NomPackage;]
[public] class NomClasse {...}
96
www.unamur.be
Packagesetvisibilité
Exemple:
package com.amazon.business;
public class Commande {...
}
97
www.unamur.be
Packagesetvisibilité
• Conséquences:
— seuls les éléments déclarés public d’une classe déclarée public sontaccessibles de l’extérieur du package (on verra une exception plus tardavec la visibilitéprotected)
— nouvelle visibilité : les éléments déclarés package sont accessibles aucode (des autres classes) du package, quelle que soit la visibilité de laclasse à laquelle ils appartiennent
— les éléments déclarésprivate restent confinés à la classe
98
www.unamur.be
PackagesetvisibilitéExemple:
99
...
...
www.unamur.be
Packagesetvisibilité
• Lespackagessontégalementutilespourlenommage— lespackagessontorganiséshiérarchiquement
(≠ hiérarchiedeclasses!)— chacunpossèdeunnomqualifié (fullyqualifiedname)qui
reprendtoutelahiérarchiedupackageetl’identifiedemanièreabsolue§ Ex:com.amazon.business, com.amazon.gui,...
— unmêmepackagenepeutdonccontenirdeuxsous-packages(directs)demêmenom
— unmêmepackagenepeutpasnonpluscontenirdirectementdeuxclassesdemêmenom
100
www.unamur.be
Packagesetvisibilité
• Touteclassepossèdeunnomcourt ounomrelatif (p/raupackage)
— Exemple:Commande
• Touteclassepossèdeaussiunnomqualifié (fullyqualifiedname)ounomabsolu :nomQualPackage.nomClasse
— Exemple:com.amazon.business.Commande
• Siducodedoitaccéderàuneclassedumêmepackage,ilpeutsecontenterdunomcourt
• Siducodedoitaccéderàuneclassed’unautrepackage,ildoitutiliser:
— soitlenomqualifié,
— soitimporter laclasseoulepackagedanslaquelleellesetrouve
101
www.unamur.be
Packagesetvisibilitépackage com.amazon.gui;
class Menu {...void choisirItem(int i) {
...com.amazon.business.Commande maCom = ...;float total = maCom.calculeMontant();
}...
}
102
www.unamur.be
Packagesetvisibilitépackage com.amazon.gui;import com.amazon.business.Commande;
class Menu {...void choisirItem(int i) {
...Commande maCom = ...;float total = maCom.calculeMontant();
}...
}
103
www.unamur.be
Packagesetvisibilitépackage com.amazon.gui;import com.amazon.business.*;
class Menu {...void choisirItem(int i) {
...Commande maCom = ...;float total = maCom.calculeMontant();
...Article monArticle = ...;
float val = monArticle.donneValeur();}...
}
104
www.unamur.be
Packagesetvisibilitépackage com.amazon.gui;import com.amazon.business.Commande;
class Menu {...void choisirItem(int i) {...Commande maCom = ...;float total = maCom.calculeMontant();}...
}
105
possibilité de conflit de noms sicom.amazon.gui possède
également une classenommée Commande
www.unamur.be
Packagesetvisibilitépackage com.amazon.gui;import com.amazon.business.Commande;import com.amazon.db;
class Menu {...void choisirItem(int i) {
...Commande maCom = ...;float total = maCom.calculeMontant();
}...
}
106
possibilité de conflit de noms sion importe une autre classe
de même nomEx: Menu importe com.amazon.dbqui possède également une classe
nommée Commande
www.unamur.be
Packagesetvisibilité
• Syntaxe(réviséemaistoujourssimplifiée)desdéclarationsdeclasses:
[package NomPackage;]
[import NomPackage [.NomPackage]* [.NomClasse]; ]*
[public] class NomClasse {...}
107
www.unamur.be
Objetsetvariables
• Lesdonnéesduprogrammesontstockéesdansdesvariables
• Toutevariablepossèdeuntype
• Untypeestsoit
— untypeprimitif
§ ex:int, boolean, char,...
— untyped’objets
§ ex:String, MultiSet, Commande, int[],...
108
www.unamur.be
Typesprimitifs
• Untypeprimitifdéfinitunensembledevaleurs
— ex:int définitunensembledevaleurstellesque0,12,544226,...
• EnJava,ilexiste8typesprimitifs.Ilssontprédéfinis dansle
langage.
• L’utilisateurnepeutpasendéfinirdenouveaux.
109
www.unamur.be
Typesprimitifs
110
www.unamur.be
Typesd’objets
• Untyped’objetdéfinitunensembled’objets— ex:LetypeCommande définitl’ensembledescommandes
qu’Amazon.comestsusceptibledetraiter— ex:LetypeMultiSet définitl’ensembledesmulti-ensemblesd’entiers
• Leprogrammeurpeutdéfinirautantdenouveauxtypesd’objetsqu’illedésire— c’estencelaqueJavaetlesautreslangagesOOfacilitentl’abstractionpar
lesdonnées!
• Diverstypesd’objetssontnéanmoinsfournisauprogrammeurdansdespackagesdéfinispard’autres— ex:lepackagejava.lang fournitletype String— NB:contrairementàlarègle, java.lang nedoitpasêtreimporté
pourquel’onpuisseenutiliserlestypesvialeursnomscourts
111
www.unamur.be
Variablesprimitives
• Une variabled’untypeprimitif (aka variabledebase aka variableprimitive)contientunevaleurdecetype— ex:boolean laVieEstBelle = true;
— ex:int i = 6 + 9;
§ 6 + 9 estuneexpressiondont l’évaluationdonne15i.e.unevaleurdetype int
• Règlesd’initialisation:— Toutevariablepeut êtreinitialiséeaumomentdesadéclaration— Elledoit l’êtreavanttouteutilisation
§ ex:int j; int i = j + 2; génèreuneerreurdecompilation
112
www.unamur.be
Variablesderéférence
• Unevariabledetypeobjet (=toutevariablenonprimitive)contientuneréférenceversunobjetdecetype— rappel:lesString etlestableauxsontdestypesd’objets!
• Unetellevariableestégalementappeléevariablederéférenceou,danscertainslangages,pointeur
• Ex:Commande maCom = <expr> où <expr> estuneexpressiondontl’évaluationfournituneréférenceversuneCommande
113
Commande 749674
maCom
www.unamur.be
Variablesderéférence
• Ex:int[] monTab = <expr> où<expr>estuneexpressiondontl’évaluationfournituneréférenceversuntableaud’entiers
• Donc,enJava,toutevariablenonprimitiveestunpointeur !• Lesrèglesd’initialisations’appliquentaussiauxvariablesde
référence• Unevariablederéférencequinepointeversaucunobjetala
valeurspécialenull:
114
monTab [32,4,18]
nullou
www.unamur.be
Systèmesdeprogrammation
115
Scheme Interpreter
Scheme Program
C++ Compiler
C++ Program
Machine
Object Files
www.unamur.be
JavaVM
116
• Portabilité– si une implémentation de la Java VMexiste pour l’architecture de votremachine, vous pouvez alors exécutertous les programmes Java
• Securité– une VM peut restreindre l’accès duprogramme à la machine réelle
• Simplicité– les instructions de la VM instructionspeuvent être plus simple que lesinstructionsmachines
Java Compiler
Java Program
Java Virtual Machine
class Files
Machine
www.unamur.be
Exécutiond’unprogrammeJava
• L’exécution d’unprogramme Javaest une séquenced’exécutions deméthodes (en commençant parl’appel à laprocédure public static void main(String[] args) )
• Audébutdel’exécution d’une méthode,unactivationrecordest empilé surlapile (stack)— une entréepourchaqueparamètre deméthode— une entréepourchaque variablelocale
• L’activation recordest dépilé delapilequand laméthode setermine
• Vuquelesappels deméthode peuvent être imbriqués,ceprocessus est récursif
117
www.unamur.be
Stacketheap
• LamachinevirtuelleJavapossèdedeuxmémoires:
— lestack (pile)
— leheap (tas)
• Lesvariableslocales (typiquement,cellesquisontdéclaréesà
l’intérieurdesméthodes)résidentsurlestack,qu’elles
contiennentunevaleurouuneréférence
• Lesobjetsrésidentdansleheap
118
www.unamur.be
Stacketheappublic static void doThing(){
int i = 6;int j;int[] a = {1,3,5,7,9};int[] b = new int[3];String s = “abcdef“;String t = null;…
}
stack heap
119
www.unamur.be
Stacketheappublic static void doThing(){
int i = 6;int j;int[] a = {1,3,5,7,9};int[] b = new int[3];String s = “abcdef“;String t = null;…
}
stack heap
Déclaration de la variable locale iet assignation de la valeur 6Question : type primitif outype de données ?
120
www.unamur.be
Stacketheappublic static void doThing(){
int i = 6;int j;int[] a = {1,3,5,7,9};int[] b = new int[3];String s = “abcdef“;String t = null;…
}
stack heap
i
Déclaration de la variable locale iet assignation de la valeur 6Question : type primitif outype de données ?
6
121
www.unamur.be
Stacketheappublic static void doThing(){
int i = 6;int j;int[] a = {1,3,5,7,9};int[] b = new int[3];String s = “abcdef“;String t = null;…
}
stack heap
i 6
j
122
www.unamur.be
Stacketheapstack heap
i 6
ja
[1,3,5,7,9]
int[ ]
123
public static void doThing(){
int i = 6;int j;int[] a = {1,3,5,7,9};int[] b = new int[3];String s = “abcdef“;String t = null;…
}
www.unamur.be
public static void doThing(){
int i = 6;int j;int[] a = {1,3,5,7,9};int[] b = new int[3];String s = “abcdef“;String t = null;…
}
Stacketheapstack heap
i 6
ja
[1,3,5,7,9]
int[ ]
124
www.unamur.be
Stacketheappublic static void doThing(){
int i = 6;int j;int[] a = {1,3,5,7,9};int[] b = new int[3];String s = “abcdef“;String t = null;…
}
stack heap
i 6
ja
[1,3,5,7,9]
int[ ]
125
www.unamur.be
Stacketheappublic static void doThing(){
int i = 6;int j;int[] a = {1,3,5,7,9};int[] b = new int[3];String s = “abcdef“;String t = null;…
}
stack heap
i 6
ja
[1,3,5,7,9]
int[ ]
b[0,0,0]
int[ ]
126
www.unamur.be
Stacketheappublic static void doThing(){
int i = 6;int j;int[] a = {1,3,5,7,9};int[] b = new int[3];String s = “abcdef“;String t = null;…
}
stack heap
i 6
ja
[1,3,5,7,9]
int[ ]
b[0,0,0]
int[ ]
127
www.unamur.be
Stacketheappublic static void doThing(){
int i = 6;int j;int[] a = {1,3,5,7,9};int[] b = new int[3];String s = “abcdef“;String t = null;…
}
stack heap
i 6
ja
[1,3,5,7,9]
int[ ]
b[0,0,0]
int[ ]
128
www.unamur.be
Stacketheappublic static void doThing(){
int i = 6;int j;int[] a = {1,3,5,7,9};int[] b = new int[3];String s = “abcdef“;String t = null;…
}
stack heap
i 6
ja
[1,3,5,7,9]
int[ ]
b[0,0,0]
int[ ]
“abcdef”
String
s
129
www.unamur.be
Stacketheappublic static void doThing(){
int i = 6;int j;int[] a = {1,3,5,7,9};int[] b = new int[3];String s = “abcdef“;String t = null;…
}
stack heap
i 6
ja
[1,3,5,7,9]
int[ ]
b[0,0,0]
int[ ]
“abcdef”
String
s
130
www.unamur.be
Stacketheappublic static void doThing(){
int i = 6;int j;int[] a = {1,3,5,7,9};int[] b = new int[3];String s = “abcdef“;String t = null;…
}
stack heap
i 6
ja
[1,3,5,7,9]
int[ ]
b[0,0,0]
int[ ]
“abcdef”
String
s
131
www.unamur.be
Stacketheappublic static void doThing(){
int i = 6;int j;int[] a = {1,3,5,7,9};int[] b = new int[3];String s = “abcdef“;String t = null;…
}
stack heap
i 6
null
ja
[1,3,5,7,9]
int[ ]
b[0,0,0]
int[ ]
“abcdef”
String
st
132
www.unamur.be
Stacketheappublic static void doThing(){
int i = 6;int j;int[] a = {1,3,5,7,9};int[] b = new int[3];String s = “abcdef“;String t = null;…
}
stack heap
i 6
ja
[1,3,5,7,9]
int[ ]
b[0,0,0]
int[ ]
“abcdef”
String
stALTERNATIVE
133
www.unamur.be
Stacketheappublic static void doThing(){
int i = 6;int j;int[] a = {1,3,5,7,9};int[] b = new int[3];String s = “abcdef“;String t = null;…
}
stack heap
i 6
null
ja
[1,3,5,7,9]
int[ ]
b[0,0,0]
int[ ]
“abcdef”
String
st
Après l’exécution de ces instructions, le stack etle heap contiennent :
134
www.unamur.be
Créationd’objets
• Lafaçonstandarddecréerunnouvelobjetdansleheap estd’utiliserl’instructionnew— ex:int[] a = new int[3];
• new apoureffet— d’allouerunepartieduheap austockaged’unobjetdutypeindiqué
§ untableaud’entiersdelongueur 3dansl’exemple
135
stack heap
aint[ ]
www.unamur.be
Créationd’objets
• new apoureffet(suite)— d’initialiserl’objet (paslavariablederéférence!)enappelantune
méthodeparticulière dutypeappeléeconstructeur(cf.CreatedeCRUD)§ dansl’exemple,leconstructeurinitialiselecontenudutableauà[0,0,0]
(contenupardéfaut)
136
§ NB: new peut également être utilisé avec des paramètres pour initialiser le contenu de l’objet à d’autres valeurs que celles par défaut
a [0,0,0]
int[ ]
www.unamur.be
Créationd’objets
• new apoureffet(suite)— d’assignerune(valeurde)référence àl’objetnouvellementcréé,quile
distinguedetouslesautresobjetsprésentsdansleheap.Onparleaussid’identifiant del’objet(objectID).
137
a [0,0,0]
int[ ]
www.unamur.be
Créationd’objets
• new apoureffet(suiteetfin)— deretournercettevaleurderéférence
§ dansl’exemple,cettevaleurestensuite assignéeàlavariable a vialesymbole =
138
a [0,0,0]
int[ ]
www.unamur.be
Créationd’objets
• Ilexiste2formesparticulièresdecréationd’objets— pourlestableaux,parex:
§ int[] a = {1,3,5,7,9};
— pourles String, parex:§ String s = “abcdef“;
• Cesformesparticulièressontdesraccourcissyntaxiquesdéfinisdanslelangage
• Ilsont(presqu’) exactementlemêmeeffetqu’unnew— maisun new paramétréi.e.quiinitialiseraitlecontenude
l’objetàl’aidedesvaleursindiquéesetnonavecdesvaleurspardéfaut
139
www.unamur.be
Partagederéférences
• Siunevariablederéférencesevoitdonnerunevaleurde
référencedéjàassignéeàuneautrevariable,lesdeuxvariables
partagent(laréférencevers)l’objet
• L’objetdevientalorsaccessibleparcesdeuxvariables
• Partagederéférences=aliasing (enanglais)
140
www.unamur.be
Partagederéférencespublic static void doThing() {
…String s = new String (“hello”);
String t = s;…
}
141
www.unamur.be
public static void doThing() {…String s = new String (“hello”);
String t = s;…
}
Partagederéférences
142
s
“hello”String
www.unamur.be
Partagederéférencespublic static void doThing() {
…String s = new String (“hello”);
String t = s;…
}
143
s
“hello”Stringt
www.unamur.be
Partagederéférencespublic static void doThing() {
…String s = new String (“hello”);
String t = s;s = new String (“bye”);…
}
144
st
“hello”String
“bye”
String
www.unamur.be
Partagederéférences
145
st
“hello”String
“bye”
String
public static void doThing() {…String s = new String (“hello”);
String t = s;s = new String (“bye”);…
}
www.unamur.be
Partagederéférences
146
st
“hello”String
“bye”
String
public static void doThing() {…String s = new String (“hello”);
String t = s;s = new String (“bye”);…
}
www.unamur.be
PartagederéférencesAutre exemple:• Sicesinstructions(voirci-dessous)sontexécutéesàpartirdelasituationA,on
obtientlasituationB:j = i;b = a;t = s;
147
6
null
stack heap
[1,2,3,5,9]
[0,0,0]
"abcdef"
ij
a
bs
t
6
6
stack heap
[1,2,3,5,9]
[0,0,0]
"abcdef"
ij
a
bs
t
Situation A Situation B
StringString
int[ ]
int[ ]
int[ ]
int[ ]
www.unamur.be
L’opérateur==
• L’opérateur== déterminesideuxvariablesont:— pourlestypesdedonnées,lamêmeréférence— pourlestypesprimitifs,lamêmevaleur
• L’évaluationde<expr1> == <expr2> retourneunevaleurbooléenne
• Utilisationstypiques— Deuxvariablesprimitivesont-elleslamêmevaleur?
§ Ex:i == j— Unevariablederéférencepointe-t-elleversunobjetounon?
§ Ex:t == null— Deuxvariablespartagent-ellesuneréférence?
§ Ex:a == b
148
www.unamur.be
Garbagecollection
• Legarbagecollector (ouramasse-miettes)estlapartiedelamachinevirtuelleJavachargéedelibérerlamémoire(heap)occupéeparlesobjetsquinesontplusréférencés
• Leprocessusdegarbagecollectionsedéclenchepériodiquementoulorsquelamémoireestsaturée
149
6
6
stack heap
[1,2,3,5,9]
[0,0,0]
"abcdef"
ij
a
bs
t
Situation B § Si le GC se déclenche dans la situation B, l’espace occupé par le tableau contenant [0,0,0] sera libéré.
§ Le GC s’occupe de la destruction (Delete de CRUD) des objets. Le programmeur ne doit donc (généralement) pas s’en occuper.
String
int[ ]
int[ ]
www.unamur.be
Mutabilité• Unobjetestmutable ssi sonétat peutchanger• Danslecascontraire,ilestimmutable• Ilappartientauconcepteurdelaclassededéciderdesamutabilité• LesString sontimmutables• Iln’existepasdeméthodeoud’opérateurquimodifie (Update)uneString unefois
qu’elle aétécréée— Ex:ApartirdeB,exécutert = t + “g“ donneC
150
6
6
stack heap
[1,2,3,5,9]
[0,0,0]
"abcdef"
ij
a
bs
t
Situation B
6
6
stack heap
[1,2,3,5,9]
[0,0,0]
"abcdef"
ij
a
bs
t
Situation C
"abcdefg"
String
int[ ]
int[ ] String
int[ ]
int[ ]
String
www.unamur.be
Mutabilité• Parcontre,lestableauxsontmutables• monTab [<expr1>] = <expr2> apoureffetd’assigneràla<expr1>ème
celluledutableaulavaleurde<expr2> (pourpeuque<expr1> s’évalueàunevaleurd’indicecomprisedanslesbornesdutableauetque<expr2> soitdutyperequis)— Ex:ApartirdeC,exécuterb[0] = i donneD
151
6
6
stack heap
[1,2,3,5,9]
[0,0,0]
"abcdef"
ij
a
bs
t
Situation C
"abcdefg"
6
6
stack heap
[6,2,3,5,9]
[0,0,0]
"abcdef"
ij
a
bs
t
Situation D
"abcdefg"
int[ ]
int[ ]
int[ ]
int[ ]
String
String
String
String
www.unamur.be
Mutabilité
• String estimmutable,alorsqueStringBuilder estmutable— String.concat créeunnouvelobjetString— StringBuilder.appendmutel’ancienobjetdetypeStringBuilder
152
A string literal is a reference to an instance of class String (§4.3.1, §4.3.3).
Moreover, a string literal always refers to the same instance of classString. This is because string literals - or, more generally, strings that are the values of constant expressions (§15.28) - are "interned" so as to share unique instances, using the method String.intern.
www.unamur.be
public class Strings {public static void test (…) {
String s = new String ("hello");String t = new String ("hello");StringBuilder sb =
new StringBuilder("he");StringBuilder tb = sb;String s1 = "hello";String t1 = "hello";
sb.append (“llo");tb.append (" goodbye!");s.concat (" goodbye!");t = s.concat (" goodbye!");
}}
MutabilitéStringetStringBuilder
153
s “hello”
t
sb
tb
“hello”String
“he”
StringBuilder
String
www.unamur.be
MutabilitéStringetStringBuilder
154
s “hello”
t
sb
tb
“hello”String
“he”
StringBuilder
s1
t1 “hello”
String
String
public class Strings {public static void test (…) {
String s = new String ("hello");String t = new String ("hello");StringBuilder sb =
new StringBuilder("he");StringBuilder tb = sb;String s1 = "hello";String t1 = "hello";
sb.append (“llo");tb.append (" goodbye!");s.concat (" goodbye!");t = s.concat (" goodbye!");
}}
www.unamur.be
MutabilitéStringetStringBuilder
155
s “hello”
t
sb
tb
“hello”String
“he”
StringBuilder
s1
t1 “hello”
Les spécifications de String ne sontpas suffisantes pour déterminer si s,t, s1 et t1 référencent le mêmeobjet.
Etc’est tout-à-faitacceptabledefaireainsi !
String
String
public class Strings {public static void test (…) {
String s = new String ("hello");String t = new String ("hello");StringBuilder sb =
new StringBuilder("he");StringBuilder tb = sb;String s1 = "hello";String t1 = "hello";
sb.append (“llo");tb.append (" goodbye!");s.concat (" goodbye!");t = s.concat (" goodbye!");
}}
www.unamur.be
public class Strings {public static void test (…) {
String s = new String ("hello");String t = new String ("hello");StringBuilder sb =
new StringBuilder("he");StringBuilder tb = sb;String s1 = "hello";String t1 = "hello";
sb.append (“llo");tb.append (" goodbye!");s.concat (" goodbye!");t = s.concat (" goodbye!");
}}
MutabilitéStringetStringBuilder
156
s “hello”
t
sb
tb
“hello”String
“hello”
StringBuilder
s1
t1 “hello”
String
String
www.unamur.be
MutabilitéStringetStringBuilder
157
s “hello”
t
sb
tb
“hello”String
“hello goodbye”
StringBuilder
s1
t1 “hello”
String
String
public class Strings {public static void test (…) {
String s = new String ("hello");String t = new String ("hello");StringBuilder sb =
new StringBuilder("he");StringBuilder tb = sb;String s1 = "hello";String t1 = "hello";
sb.append (“llo");tb.append (" goodbye!");s.concat (" goodbye!");t = s.concat (" goodbye!");
}}
www.unamur.be
MutabilitéStringetStringBuilder
158
s “hello”
t
sb
tb
“hello”String
“hello goodbye”
StringBuilder
s1
t1 “hello”
String
String
“hello goodbye”
String
public class Strings {public static void test (…) {
String s = new String ("hello");String t = new String ("hello");StringBuilder sb =
new StringBuilder("he");StringBuilder tb = sb;String s1 = "hello";String t1 = "hello";
sb.append (“llo");tb.append (" goodbye!");s.concat (" goodbye!");t = s.concat (" goodbye!");
}}
www.unamur.be
public class Strings {public static void test (…) {
String s = new String ("hello");String t = new String ("hello");StringBuilder sb =
new StringBuilder("he");StringBuilder tb = sb;String s1 = "hello";String t1 = "hello";
sb.append (“llo");tb.append (" goodbye!");s.concat (" goodbye!");t = s.concat (" goodbye!");
}}
MutabilitéStringetStringBuilder
159
s “hello”
t
sb
tb
“hello”String
“hello goodbye”
StringBuilder
s1
t1 “hello”
String
String
String
“hello goodbye”
String
“hello goodbye”
www.unamur.be
MutabilitéStringetStringBuilder
160
s “hello”
t
sb
tb
“hello”String
“hello goodbye”
StringBuilder
s1
t1 “hello”
String
String
String
“hello goodbye”
String
“hello goodbye”
public class Strings {public static void test (…) {
String s = new String ("hello");String t = new String ("hello");StringBuilder sb =
new StringBuilder("he");StringBuilder tb = sb;String s1 = "hello";String t1 = "hello";
sb.append (“llo");tb.append (" goodbye!");s.concat (" goodbye!");t = s.concat (" goodbye!");
}}
www.unamur.be
MutabilitéStringetStringBuilder
161
s “hello”
t
sb
tb
“hello”String
“hello goodbye”
StringBuilder
s1
t1 “hello”
String
String
String
“hello goodbye”
String
“hello goodbye”
public class Strings {public static void test (…) {
String s = new String ("hello");String t = new String ("hello");StringBuilder sb =
new StringBuilder("he");StringBuilder tb = sb;String s1 = "hello";String t1 = "hello";
sb.append (“llo");tb.append (" goodbye!");s.concat (" goodbye!");t = s.concat (" goodbye!");
}}
www.unamur.be
Mutabilitéetpartage
• Siunobjetmutableestpartagéparplusieursvariables,toutemodificationdel’objeteffectuéeàpartird’unedesvariablesestvisibleautraversdesautres
• Ex:danslasituationD(voirslide151),a[0] == i estévaluéeàtrue, toutcommeb[0] == i, bienquelamodificationdutableauaitétéfaiteviab
162
www.unamur.be
Appelsdeméthodes• EnJava,l’appelàuneméthodem sefaitvial’instruction
<expr>.m(<expr1>, <expr2>,...,<exprn>) etesttraitécommesuit:— <expr> estévaluéedemanièreàfournir laclasse(siméthodestatique)ou
l’objetdontoninvoque laméthode§ si<expr> estévaluéeànull,l’exécutionserainterrompueparune
NullPointerException— lesexpressions<expr1>, <expr2>,...<exprn> sontévaluées(degauche
àdroite)demanièreàfournir lesparamètreseffectifsdel’appel— unactivationrecord estcréédanslestackréservantdelamémoirepour les
paramètresformelsetvariableslocalesdelaméthode— lesparamètresformelsprennent lesparamètreseffectifspourvaleursdansle
stack(passagedeparamètresparvaleur)§ i.e.lesvaleursdesparamètreseffectifssontcopiées dansl’activationrecord
— lecontrôleestpasséàlaméthode.C’estledispatching.Cemécanismecomplexeseraabordéultérieurement.
163
www.unamur.be
Appelsdeméthodes
• Exemple
class Arrays {...public static void multiplies(int[] a, int m) {// multiplie par m chaque élément du tableau d’entiers aif (a == null) return;for (int i = 0 ; i < a.length; i++) a[i]=a[i]*m;
}...
}
164
www.unamur.be
Appelsdeméthodes
• Exemple(suite).Soitl’appel:int[] b = {1,3,5,7,9};Arrays.multiplies(b,2);
165
stack heap
[1,3,5,7,9]b
2
stack heap
[1,3,5,7,9]b
stack heap
[2,6,10,14,18]b
Avant l’appelà multiplies
Juste après l’appelà multiplies
Après le retourde multiplies
amActivation
record i
int[ ] int[ ] int[ ]
www.unamur.be
Typechecking
• Javaestunlangagefortementtypé— lecompilateur vérifiequetouteslesassignations etquetouslesappels
sontcorrectsdupointdevuedutypage— touteerreuràceniveauestsanctionnéeparuneerreurdecompilation
• Lavérificationdutypage(typechecking)requiertque— toutedéclarationdevariableindiqueletypedecelle-ci— toutedéclarationdeméthodeindiquesasignature
§ lestypesdesparamètres
§ letypedurésultat§ (lestypesd’exceptionsrenvoyés-- voirplus loin)
166
www.unamur.be
Typechecking
• Cesinformationsdetypagepermettentaucompilateurdedéduireletypeapparentdetouteexpression
• Lecompilateurutilisealorsletypeapparentpourvérifierlacorrectiondesassignationsetdesappels
• Exemple
int y = 7;
int z = 3;
int x = Num.gcd(z,y);
167
class Num {
public static int gcd(int n, int d) {
while (n != d)
if (n > d) n = n - d; else d = d - n;
return n;
...
}
Correspondancedestypesapparentsdesparamètreseffectifsetdes
paramètresformels
www.unamur.be
Typecheckingettypesafety
• Letypechecking àlacompilationestundesmécanismesdeJavapermettantdegarantirquelesprogrammes(compilés!)sonttypesafe
— i.e.aucuneerreurdetypage(typemismatch)nepeut survenirdurantsonexécution
— i.e.iln’estpaspossibleque leprogrammemanipuledesdonnéesd’un typealorsqu’il s’attendàcequ’ellessoientd’unautretype
§ exemple:String s = new Commande(); // non valide
• Autotal,cesmécanismessontaunombrede3.Lesdeuxautressont
— lagestionautomatiquedelamémoireaka automatic storagemanagement
— lavérificationdes(non-)dépassements delimitesdanslestableauxaka array bound checking
168
www.unamur.be
Typecheckingettypesafety
Typesafety=
typechecking
+automaticstoragemanagement
+ arrayboundchecking
169
www.unamur.be
Automaticstoragemanagement
• Ils’agitdel’allocationetladésallocationautomatiquedelamémoiredansleheap
• EnJava,c’estlamachinevirtuellequis’occupedetoutcelasansqueleprogrammeurdoives’ensoucier
— elles’occupedel’allocationlorsdechaquecréationd’objet (voirletraitementdunew,ci-avant)
— elles’occupedeladésallocation lorsque l’objetn’estplusréférencé(voirgarbage
collection, ci-avant)
• EnCetC++,cesmécanismesn’existentpas.C’estauprogrammeurqu’ilincombed’écrirelui-mêmelecoded’allocationetdedésallocation delamémoire
170
www.unamur.be
Automaticstoragemanagement• Exempled’allocationdynamiquedemémoireenC
struct foo *ptr;
...
ptr = (struct foo *) malloc (sizeof (struct foo));
if (ptr == 0) abort ();
memset (ptr, 0, sizeof (struct foo));
• Ladésallocationsefaitviaunfree (ptr);• Cettefaçondefairecomportaitdeuxproblèmesmajeurs(etcorrélés)
— complexificationducode
— risquesd’introduction d’erreurs,dont lesfameuses« dangling references »§ i.e.désallocationd’espacemémoiretoujoursréférencéparleprogramme
(sipartagederéférences)
171
www.unamur.be
Hiérarchiedestypes
• Souvenez-vousdel’exempleintroductif…
172
Quadrilatère
Rectangle
Carré
Polygone
Triangle PentagoneHexagone
FormeGéométrique
Cercle
...
...
...
www.unamur.be
Hiérarchiedestypes• EnJava,lestypesnonprimitifs(i.e.lestypesd’objets)sontorganisésde
manièrehierarchique• UntypedonnéTpeutavoirplusieurssupertypes,sesancêtres dansla
hiérarchie• Ilestditêtreunsous-type (subtype)dechacundesessupertypes• Exemple
— Quadrilatère unsupertypedeRectangle etCarré quiensontdessous-types
— Rectangle estunsupertypedeCarré
— Rectangle et Carré sontdessous-typesde Quadrilatère
173
Quadrilatère
Rectangle
Carré
www.unamur.be
Hiérarchiedestypes
• Danslalittérature,ontrouveparfoisd’autresterminologies
— superclasse (superclass)≈supertype
— sous-classe (subclass)≈sous-type
— « un typeT1étend (extends)untypeT2 »≈« T1estunsous-typedeT2 »
• L’organisationhiérarchiquedestypesestunmécanismed’abstractionpermettant,quandc’estapproprié,d’ignorer les différences entretypespourneplusvoirquecequeleurscomportementsontdecommun etquisetrouvedansleurssupertypescommuns.
174
www.unamur.be
Hiérarchiedestypes
• Larelationdesous-typageest
— transitive
§ siRestunsous-typedeSetSestunsous-typedeT,alorsRestun
sous-typedeT
— réflexive
§ Testunsous-typedelui-même
175
www.unamur.be
HiérarchiedestypesPrincipedesusbstitution
• « SiSestunsous-typedeT,lesobjetsdetypeSdoiventpouvoirêtreutilisésdanstoutcontextequirequiertdesobjetsdetypeT »
• Implications— touteslesméthodesdeT doiventêtredisponiblesdansS
§ vérifiéparlecompilateurJava
— lesappelsàcesméthodesdoiventproduirelemêmecomportementdansSetT§ nonvérifiable parlecompilateurpuisquecelareviendraitàpouvoirprouverque
deuxprogrammesontlemêmecomportement
§ doitêtregarantiparleprogrammeur
• Nousverronsultérieurementcommentconstruiredestypesquivérifientleprincipedesubstitution
• Pourl’instant,nousnouscontenteronsd’utiliserdestypesprédéfinissupposésoffrircesgaranties
176
www.unamur.be
HiérarchiedestypesObject
• Enjava,ilexisteuntypeObject quiestsupertype detouslestypes(prédéfinisounon).
• C’estl’ancêtrecommun,lesommetdelahiérarchie
• String, StringBuilder etlestypesdetableauxsontdonc,commetouslesautres,dessous-typesd’Object
• Object possèdenotammentdeuxméthodes
— boolean equals(Object o)
— String toString()
• L’utilitédecesméthodesseradiscutéeplusavantmais,àcestade,retenonsqu’ellespeuventêtreinvoquéessurtoutobjetJava
— ex:boolean lesMemes = s.equals(t) estvalidequelsquesoientlestypesrespectifsdes ett (saufpour lestypesprimitifs,bienentendu)
177
www.unamur.be
HiérarchiedestypesValiditédesassignations
• Règle:enJava,l’assignationv=<expr> (avecv variablederéférence)estvalidesiletype(apparent)de<expr> estunsous-typedutype(apparent)dev
• Exemple...int[] a = new int[3];String s = “abcdef“;Object o1 = a;Object o2 = s;...
178
www.unamur.be
HiérarchiedestypesValiditédesassignations
• Cetextraitdecodeestparfaitementvalideetproduitlerésultatsuivant
179
stack heap
[0,0,0]
"abcdef"
as
Aprèsint[] a = new int[3];
String s = “abcdef“;
stack heap
[0,0,0]
"abcdef"
as
o1
AprèsObject o1 = a;Object o2 = s;
o2
int[ ] int[ ]
StringString
www.unamur.be
AprèsObject o1 = a;Object o2 = s;
HiérarchiedestypesValiditédesassignations
• Cetextraitdecodeestparfaitementvalideetproduitlerésultatsuivant
180
Le type déclaré de o1est Object Le type effectif de o1
est int[3]
stack heap
[0,0,0]
"abcdef"
as
Aprèsint[] a = new int[3];
String s = “abcdef“;
stack heap
[0,0,0]
"abcdef"
as
o1
o2
int[ ] int[ ]
StringString
www.unamur.be
AprèsObject o1 = a;Object o2 = s;
HiérarchiedestypesValiditédesassignations
• Cetextraitdecodeestparfaitementvalideetproduitlerésultatsuivant
181
Le type déclaré de o2est Object
Le type effectif de o2est String
stack heap
[0,0,0]
"abcdef"
as
Aprèsint[] a = new int[3];
String s = “abcdef“;
stack heap
[0,0,0]
"abcdef"
as
o1
o2
int[ ] int[ ]
StringString
www.unamur.be
HiérarchiedestypesTypedéclarévstypeeffectif
• Typedéclaré (apparenttype,compile-timetype)=typed’unevariabletel
qu’ilestdonnédanssadéclaration (ilestlemêmependanttoutel’/les
exécution(s))
• Typeeffectif (actual type,runtime type)=typed’unevariableàun
momentdonnédel’exécution,déterminéparletypedel’objetqu’elle
référencedansleheap (celui-ciestdéterminéàlacréationdel’objet)
• Letypechecking (àlacompilation)esttoujourseffectuésurbasedutype
déclaré
182
www.unamur.be
HiérarchiedestypesValiditédesappelsdeméthodes
• Règle:lavaliditédesappelsdeméthodesestvérifiéedemanièreanalogueaux
assignationsi.e.
— letypedéclarédel’objetsurlequeloninvoquelaméthodedoitêtreunsous-type du
typepourlequellaméthodeaétédéfinie
— letypedéclaréd’unparamètreeffectifdoitêtreunsous-type dutypedéclarédu
paramètreformel
• Exemple...if (o2.equals(“abc“)) ... ; // valideif (o2.length == 0) ... ; // non valideif (s.size() == 0 ) ... ; // valide...
• NB:seuleslesméthodesd’Object (i.e.equals, toString,...)peuventêtre
invoquéessurn’importe queltyped’objet
183
www.unamur.be
HiérarchiedestypesTypedéclarévstypeeffectif
• Lesdeuxrèglesdevaliditéquel’onvientdevoirontpourconséquence
que,àl’exécution, letypeeffectifd’unevariableoud’uneexpressionest
toujoursunsous-typedesontypedéclaré
184
www.unamur.be
HiérarchiedestypesCasting
• Ilestcependantparfoisutiled’indiquerdansleprogrammeletypeeffectif
del’objetàl'exécution
• C’estutile,parexemple,
— pourpouvoir invoquer uneméthodesurunobjetdontletypedéclaré
l’interditmaisdontonsaitque letypeeffectiflepermet
§ ex:if (o2.size() == 0) ... ; // non valide
— pourassigneràunevariablelavaleurd'uneexpressiondont letypedéclaré
l’interditmaisdontonsaitque letypeeffectiflepermet
§ ex:s = o2; // non valide
185
www.unamur.be
HiérarchiedestypesCasting
• Celapeutsefairevialecasting• Exemple
if (((String)o2).size() == 0) ... ; // valide
s = (String)o2; // valide
• Lecastingprovoquelasurvenanced’unevérificationdetypeàl’exécution— (String)o2 demandelavérificationdufaitqueletypeeffectifdeo2 soit
String
• Silavérificationréussit,lesinstructionssontexécutées• Silavérificationéchoue,aulieud’exécuterlesinstructions,lamachine
virtuellerenvoieuneClassCastException— Dansnotrecas,(String)o2 réussitetletestainsique l’affectationsontexécutés
186
www.unamur.be
Conversiondetypes
• Javaautorisecertainesconversionsimplicites devaleursd’untypeenvaleursd’unautretype
• Seulslestypesprimitifs sontconcernésparlaconversion
• Exemple:laconversiondecaractères(char)entypesnumériques(int,parex)
char c = ‘a’;
int n = c; // valide
• Lorsquelecompilateurrencontredesconversionsimplicites,ilgénèrelesinstructionsquieffectuentlaconversion
• Ondiraqueleschar peuventêtreélargis (widened)enint
— Plusgénéralement, lescharpeuventêtreélargisàtouslestypesnumériques (saufshort)
187
www.unamur.be
Conversiondetypes
• LesconversionsdetypesimplicitesautoriséesenJavasontdonnéesdanslechapitre5du« TheJavaLanguageSpecification»
• Exemple:widening detypesprimitifsautorisés— byte vers short,int,long,float oudouble— short vers int,long,float oudouble— char vers int,long,float oudouble— int vers long,float oudouble— long vers float oudouble— float vers double
• Pasàconnaîtremaisvousyréférerencasdedoute
188
www.unamur.be
Overloading(surcharge)
• EnJava,commedanslaplupartdeslangages,lesopérateurssontoverloadés(surchargés)
• Exemple— l’opérateur+ estdéfinipourplusieurs typesd’opérandes :int + int,
float + float, int + float, float + int, int + long, etc...
• Enoutre,enJava,leprogrammeurpeutoverloader lesméthodesqu’ildéfinit
• Exemple:soitlaclasseC possédantlesméthodesstatic int comp(int, long) // def 1
static int comp(long, int) // def 2
static int comp(long, long) // def 3
189
www.unamur.be
Overloading(surcharge)
• OnditquelaclasseC surchargelenomdeméthodecomp• L’overloadingestutilemaisilpeutêtresourced’ambiguïtéspourle
compilateur• Exemple:
— soitlesdéclarations int x; long y; float z;
— or, Javaadmetlaconversiond’int enlong ainsiquelaconversiondelong enfloat
— dèslors,àquelledéfinition doitobéir l’appelC.comp(x,y)?§ def.1?
◆ OK carcorrespondanceparfaitedestypesdesparamètreseffectifsetformels
§ def.2?◆ non,carconversiondelong en int nonautorisée
§ def.3?◆ OKaussi carx peutêtreconvertien long !
190
www.unamur.be
Overloading(surcharge)
• Lorsqueplusieursdéfinitionsdeméthodessurchargéespeuventconveniràunmêmeappeldeméthode,lecompilateur résoutl’ambiguïtéenchoisissantlaplusspécifique
• « Unedéfinitiondeméthodem1 estplusspécifique qu’uneautredéfinitionm2 sitoutappelvalideàm1 seraitégalementunappelvalideàm2 moyennantplusdeconversions »
• Dansl’exemple
— ladéf 1estplusspécifiquequeladéf 3cartoutappelàdef 1seraitvalidepourdef3moyennant laconversiondel’int (premierparamètre)enlong
— c’estdoncladéf 1quiserautiliséepour l’appelC.comp(x,y)
191
www.unamur.be
Overloading(surcharge)
• S’ilnepeuttrouverladéfinitionlaplusspécifique,lecompilateursignaleuneerreur
• Exemple— pour l’appelC.comp(x,x),iln’yapasdedéfinition plus spécifiqueparmiles3:
def1estplusspécifiquequedef3;def2estplusspécifiquequedef3;mais,dedef1etdef2,laquelleestplusspécifique? Aucune!
• Leprogrammeurpeutrésoudreunetelleambiguïtéenutilisantuneconversionexplicite detype,akauncast
• Exemple— EnécrivantC.comp((long) x, x), leprogrammeur indiquequec’estladef2
quidoitêtrechoisie
192
www.unamur.be
Overloading(surcharge)
• L’overloadingainsiquelarègledeladéfinitionlaplusspécifiques’appliquenttantauxparamètresdetypesprimitifsqu’auxtypesd’objets
• Exemple,étantdonnéeslesdéfinitionsdanslaclasseC :
static void foo(T a, int x) // def 1
static void foo(S b, long y) // def 2
avecS sous-typedeT,l’appelC.foo(e,3),oùe estdetype(apparent!)S,estambigu.
• Exercice:commentlevercetteambiguïté?
193
www.unamur.be
Dispatching
• Idée:garantirquequanduneméthodeestappeléesurunobjetdonné(objetDonné.méthode(...) ),c’estlecodefournipourcetteméthodeetcetobjet(typeeffectif)quiestexécuté
• Exemple
— String fournituneméthodeboolean equals(Object o) quirenvoietruequanddeuxStrings(laString couranteetleparamètre)ontlemêmecontenu(indépendamment deleuradressedansleheap)
§ Attention,cen’estpaslamêmechoseque==
— Object aussifournituneméthodeboolean equals(Object o) mais quirenvoietrue quand l’Object courantetleparamètresontunseuletmêmeObject (mêmeadressedansleheap)
§ Lerésultatest,pourObject,lemêmeque==
194
www.unamur.be
Dispatching
• Or,ilsepeutqu’àlacompilation,onnepuissedéterminerquelcodeappelercarseulletypeapparentestconnuducompilateur
• ExempleString t = “ab“;
Object o = t + “c“; //concaténation
String r = “abc“;
boolean b = o.equals(r);
• Siletypeapparentétaitutilisépourdéterminerlecodeàappeler,bcontiendraitfalse
• Ilestdoncnécessaired’avoirunmécanismeàl’exécution quifasseledispatchingverslecodesouhaité(ici,celuidutypeeffectifde o,c-à-dString).
195
www.unamur.be
Dispatching
• Chaqueobjet(dansleheap)contientuneréférenceversundispatchvector
• Celui-cicontientuneentréepourchaqueméthoded’untyped’objetdonné
• Undispatchvectorn’estassociéàunobjetqu’àl’exécutionenfonctiondesontypeeffectif
• Lecompilateurnefaitquegénérerlecodequiaccèdeàl’entréedelaméthodedansledispatchvectoretquisebrancheàl’endroitoùledispatchvectorditquelecodedelaméthodesetrouve
196
www.unamur.be
Dispatching
197
stack heap
< ,’’abc’’ >
or
< ,’’abc’’ >
equalsCode de
String equals
Dispatchvector deString
www.unamur.be
« Typesd’objetsprimitifs »
• Lestypesprimitifs(int,char,...)nesontpasdessous-typesd’Object
• IlsnepeuventdoncêtreutilisésdansdescontextesoùonattendunObject
— ceseraituneviolationduprincipedesubstitution
• Cecipeutêtrerésoluenutilisantdes« typesd’objetsprimitifs » ouwrappertypes
• Pourchaquetypeprimitif, ilexisteuntyped’objetcorrespondantqui« emballe »savaleurdansunobjet (quirésideradoncdansleheapetpasdanslestack)
— Letyped’objetInteger pourletypeprimitifint
— Letyped’objetCharacter pourletypeprimitifchar
— etc...
198
www.unamur.be
« Typesd’objetsprimitifs »
• Chaquetyped’objetprimitiffournitunconstructeurquipermetd’emballerunevaleurdansunobjet
— public Integer(int x)
• Al’inverse,chaquetyped’objetprimitiffournituneméthodequirenvoielavaleurcontenuedansl’objet
— public int intValue( )
• Idempourlesautrestypesd’objetsprimitifse.g.Character possèdelesméthodes
— public Character(char x)
— public char charValue( )
199
www.unamur.be
« Typesd’objetsprimitifs »
• Ontrouveégalementd’autresméthodes,parex.cellequiconstruitunobjetà
partirdelalectured’uneString
— int n = Integer.parseInt(s);
— Sis pointeversleString “1024“, n prendra lavaleur1024
• D’autresméthodessontdisponibles;ellessontdécritesdansladocumentation
dupackagejava.lang (danslequelsontregroupéstousles« typesd’objets
primitifs »)
— NB:java.lang estimportépardéfautdanstoutprogramme
200
www.unamur.be
Collectionsd’objets
• En Java,il existe une interfacecommuneà toutes lescollectionsd’objets:interfacejava.util.Collection
• C’est une interface,donc nepeut pasêtre directementinstanciée
• Deux interfacesplusspécialisées héritent deCollection :List etSet
201
www.unamur.be
InterfaceList
• Collectionordonnée d’objets
• Peut contenir desdoublons— doublon s'il existeo1,o2appartenantà laList|o1==o2ou
o1.equals(o2)
• C’est une interfacedonc nepeut pasêtre directementinstanciée
• Onutilisera habituellement letypededonnéesArrayList quiimplémente l’interface List
202
www.unamur.be
InterfaceSet
• Correspondà lanotiond’ensemble mathématique
• Nepeut pascontenir dedoublon— pourtouto1,o2quiappartiennentà l'ensemble |o1≠o2&&
!o1.equals(o2),etil yaauplusunélément null(mais ça n’est pasconseillé)
• C’est une interface,donc nepeut pasêtre directementinstanciée
• Typesdedonnées implémentant l’interface Set :HashSet etTreeSet
203
www.unamur.be
ArrayList
204
• Letyped’objetArrayList estdéfinidansjava.util
• Ilsertàreprésenterdestableauxd'objets delongueurvariable– ils’agitlàdedeuxdifférencesmajeuresparrapportauxtableauxclassiques
• Lesélémentsd’unArrayList sontnumérotésde0àn-1oùnestlalongueurcourantedel’ArrayList
• Onpeutconnaîtrelalongueurcouranted’unArrayList eninvoquantlaméthodeint size()
• Ilestgrandementrecommandédedéfinirletypedesélémentsd’unArrayList (cf.chapitresurlesGenerics).Dèslors,– unArrayList nepeutcontenirdesvaleursd’untypeprimitif, mais
uniquement des(référencesversdes)objets (attentionaumécanismed’autoboxing)
– unArrayList nedevraitpasêtreconstituéd’objetshétéroclites.
www.unamur.be
ArrayList
• Créer unnouvelArrayList (delongueur0)etdestinéàcontenirdesobjets
detypeString sefaitviaunnew• Exemple
// crée une liste vide
List<String> al = new ArrayList<>( );if (al.size() == 0 ) ... // true, size vaut 0
205
[]
al
stack heap
ArrayList<String>
www.unamur.be
ArrayList
• Ajouter unélémentaucontenud’unArrayList<T> (etdoncaugmentersataille)sefaitvialaméthodeboolean add(<T> o)
• Exemple(suitedel’exempleduslideprécédent)
al.add(“abc“); // ajoute une String “abc“ dans al
if (al.size( ) == 0 ) ... // false, al.size() vaut 1
206
[ ]
al
stack heap
ArrayList<String>
“abc“String
www.unamur.be
ArrayList
• Exemple(suitedel’exempleduslideprécédent)al.add(“def“);// ajoute une String “def“ dans al
207
[ , ]
al
stack heap
ArrayList<String>
“abc“String
“def“String
www.unamur.be
ArrayList
• Onpeutaccéder aucontenud’unArrayList<T> vialaméthode<T> get(int index)
• Exemple
String s = al.get(0)
• Remarques
— Puisquel’ArrayList esttypépourcontenirdesobjetsdetypeString uniquement,laméthodeget(…) renvoiedirectementuneString
— Silavaleurdel’indexindiquéeenparamètredépasselatailledel’ArrayList,lamachinevirtuellerenverrauneIndexOutOfBoundsException
§ Exemple:String t = (String) al.get(2) estvalideàlacompilationmaiséchoueàl’exécution
208
www.unamur.be
ArrayList
• Onpeutmodifierlecontenu d’unArrayList<T> àunindicedéterminé vialaméthode<T> set(int i, <T> o)
• Exempleint[] i = {1,2,3,4}; List<int[]> al = new Arraylist<>();al.add(new int[2]);
209
[]
i
stack heap
ArrayList<int[ ]>al
[1,2,3,4]int[ ]
[0,0]int[ ]
www.unamur.be
ArrayList
• Onpeutmodifierlecontenu d’unArrayList<T> àunindicedéterminé vialaméthode<T> set(int i, <T> o)
• Exempleint[] i = {1,2,3,4}; List<int[]> al = new Arraylist<>();al.add(new int[2]);al.set(0, i);
210
[ ]
i
stack heap
ArrayList<int[ ]>al
[1,2,3,4]int[ ]
[0,0]int[ ]
www.unamur.be
ArrayList
• Onpeutégalementeffacerlecontenud’unArrayList<T> àunindicedonnéviala
méthode<T> remove(int i)
• NB:Tantset queremove sontsusceptiblesdegénérerdes
IndexOutOfBoundsException àl’exécution
• Exemple(suitedel’exempleduslideprécédent)
al.remove(0);
211
[ ]
i
stack heap
ArrayList<int[ ]>al
[1,2,3,4]int[ ]
www.unamur.be
AutoBoxing
• Lescollectionsnepeuventcontenirquedesinstancesdetypesdedonnées (doncpasdevaleursd'untypeprimitif).
• Javafournit lemécanismed'autoboxing pourautomatiquement« emballer »untypeprimitifdansun« typed'objetprimitif »
• Exemple
List<Integer> al = new ArrayList<>( );al.add(3); // instruction valide
estéquivalentà
List<Integer> al = new ArrayList<>( );al.add(new Integer(3));
212
www.unamur.be
Unboxing
• Javafournitlemécanismed'unboxingpourautomatiquement« transformer »untyped'objetprimitifdansuntypeprimitif
• Exemple(suitedel'exempleduslideprécédent)
int x = al.get(0);
• Iln'est pasnécessaire decasterl'objet renvoyé parlaméthodeget()
213
www.unamur.be
ArrayList
• Tiens,etsionexécuteal=null maintenantetqu’ensuitelegarbage collectorsedéclenche,qu’emportera-t-il?
214
[ ]
i
stack heap
ArrayList<int[ ]>al
[1,2,3,4]int[ ]
int[] i = {1,2,3,4}; List<int[]> al = new Arraylist<>();al.add(new int[2]);al.set(0, i);al = null;
[0,0]int[ ]
www.unamur.be
ArrayList
• Tiens,etsionexécuteal=null maintenantetqu’ensuitelegarbage collectorsedéclenche,qu’emportera-t-il?
215
[ ]
i
stack heap
ArrayList<int[ ]>al
[1,2,3,4]int[ ]
int[] i = {1,2,3,4}; List<int[]> al = new Arraylist<>();al.add(new int[2]);al.set(0, i);al = null;
[0,0]int[ ]
www.unamur.be
ArrayList
• Tiens,etsionexécuteal=null maintenantetqu’ensuitelegarbagecollectorsedéclenche,qu’emportera-t-il?
216
[ ]
i
stack heap
ArrayList<int[ ]>al
[1,2,3,4]int[ ]
int[] i = {1,2,3,4}; List<int[]> al = new Arraylist<>();al.set(0, i);al = null;
[0,0]int[ ]