Académique Documents
Professionnel Documents
Culture Documents
If
Grammaire :
If Then Statement :
if (Expression) Statement
Il est executé après avoir testé l'expression, si elle est vraie, il execute
l'instruction (Statement), sinon, il ne l'execute pas.
Il est executé après avoir testé l'expression, si elle est vraie alors on execute le
bloc d'instrcutions qui suis le if, si cette expression est fausse, on execute l'instruction
qui suis le else.
Les accolades sont optionnelles, si on ne les met pas, ça compile quand même et les
instruction sont executé. On met donc les accolades par convention mais pas
seulement, en effet, quand on execute plus d'une instruction et qu'on omet les
accolades, seule la première instruction est considérée dans le if, ce qui n'est pas le
cas lorsqu'on les utilise afin de rassembler en bloc d'instruction.
Le principe du dangling else consiste a dire que le else appartiens au if qui le précède,
en effet, si on ne met pas les accolades, et qu'il y'a une succession de if, on ne sais pas
auquel appartiens le else. C'est l'une des raison pour lesquels on pensera a utiliser les
accolades pour contourner le problème.
Il est important de savoir que le if-else simple avec une instruction peut être remplacé
par un opérateur ternaire ?.
Le premier choix sera effectué si la condition est vraie, sinon il ne sera pas
effectué.
exemples de If :
1// if ( i == 2) {
i=6;
}
2// if (!n) {}
3// if (i == 3) {
i=4;
} else {
i=5;
}
4// if (i==1)
i=2 ;
else
i=3;
2. Expression Booléene
Les expression booléenes peuvent être écris via des opérateur* uniaire ( ! ou
variable), binaire (==, <, >, ≤, ≥ ,!=), ternaire (?)* via les valeurs true ou false, via des
appel de méthode qui renvoient un booléen ou encore via des variables booléenes.
exemple :
if (a>b) {
i=1;
}
3. Visibilité
Private
Exemples :
La visibilité public permet d'acceder aux champs à partir de toute les autres classe, on
peut tout y modifier et y acceder comme on veut.
La visibilité protected est utilisée lorsqu'on veut que les attribut et les méthodes de la
classe mère soit visible dans la classe fille. Du coup, au lieu de mettre le champ
comme étant private dans la classe mère, on le met protected.
Exemple :
lorsqu'on utilisera le mot clé extends, les attribut de la classe mère seront accessible
pour la classe fille et elle va donc pouvoir en hériter comme si ils étaient en private
la classe Manager aura donc également les méthode et les attribut déclaré en
protected dans la classe mère.
Cette visibilité apparaît lorsque les champ sont accessible depuis toute les classe du
même package. Pour la définir, on ne met aucun mot clé de visibilité.
Exemple :
Si la classe qui contiens les attributs déclaré comme package est dans le package
esi.util alors toute les classe qui se trouvent dans esi.util y auront accès.
4.Switch
Grammaire :
Switch Statement :
SwitchBlock :
{ {SwitchBlockStatementGroup} {SwitchLabel} }
SwitchBlockStatementGroup
SwitchLabel BlockStatement
SwitchLabel
case ConstantExpression:
case EnumConstantName :
ConstantExpression c'est les nombres,comme 2,3,4, leur valeur reste la même mais
également les String etc...
EnumConstantName :
Identifier
Exemple//
int var;
Le switch peut contenir des byte, char, short, int (ainsi que leur type référence Integer,
Character, Short etc..) ,des String et des énumération.
Attention, le switch ne peut PAS contenir de boolean ou double (ainsi que leur type
référence)
On utilise le mot clé break pour sortir du switch. Il est généralement placé a la fin du
case pour accomplir les instruction avant de quitter le switch, mais ça n'est pas
obligatoire, par contre si on oublie le break a la fin de notre case, tout les autres cas
qui le suivent seront également executé. C'est également la cause pour laquelle on ne
met pas de break a la fin du default car il est en général placé a la fin du switch.
Le mot cle default sers à exécuter un bloc d'instruction si aucun case ne correspond à
la valeur que la variable a prise. Ce mot clé est optionnel, on peut ne pas le mettre.
Exemple (avec énumération)
switch (Saison) {
case PRINTEMPS :
case ETE:
system.out.println(« En » + Saison + « Il fait beau ») ;
break;
case AUTOMNE :
case HIVER :
system.out.println(« En » + Saison + « Il fait froid ») ;
}
On remarque qu'il n'y a pas de break a la fin car on quitte le switch, mais on a du
mettre un break pour les cas PRINTEMPS et ETE afin de quitter le switch une fois
que l'instruction est exécutée.
if (i==1) {
//instruction
} else if (i < 1) {
//instruction
} else if (i> 1) {
//instruction
}
5. Import
On utilise le mot clé import lorsqu'on veut utiliser une classe qui se trouve dans un
autre package.
Ex : import monPackage.maClasse ;
Pour faire l'appel d'une méthode dans ce cas là, on mentionne le nom de la classe
ainsi que la méthode. Par exemple Math.PI
Une fois que l'import est fait on peut utiliser nomClasse sans mentionner le nom de
son package. On peut également importer toute les classe d'un package en utilisant le
joker * qui permet donc d'importer toute les classe du package cité précédemment.
L'utilisation de import static * permet d'importer toute les méthode d'une classe et de
pouvoir les utiliser sans devoir citer le nom de la classe.
Break
Le break permet d'arrêter une instruction.. On l'utilise dans les switch, les for, les
while ou les do-while.
Grammaire
BreakStatement
break Identifier(opt) ;
ex :
while {
for(…) {
break ;
}
//on se trouve ici après le break
}
dance : while {
for(…) {
break dance ;
}
}
// après le break on se trouve là
Continue
Grammaire
ContinueStatement
continue Identifier(opt)
Le continue est utilisé dans le cas d'une boucle (for et while) et d'un arrêt
inconditionnel. Si il n'y a pas de label il réitère l'instruction en cours, si il y'en a un, il
réitérer l'instruction étiquetée par le label.
Exemple :
int x = 1
for (int x = 0 ; x<= 10 ; x++) {
if (x == 7) {
system.out.println(« division par zéro ») ;
continue ;// quand on arrive a x=7 il n'effectue pas le calcul et passe au
suivant
}
double a = 1*6/(x-7) ;
system.out.println (a);
}
7. Static
static est un mot clé qui s'applique à un attribut ou une méthode et qui permet de
déclarer sans prendre compte des instances de la classe.
Exemple :
Imaginons qu'on est dans une classe Produit et qu'on met l'attribut nbProduit déclaré
comme ceci. static int nbProduit;
C'est un compteur qui va s'incrémenter dans le constructeur à chaque fois que l'on va
créer un objet Produit. Vu qu'on l'a déclaré static, le compteur va s'incrémenter pour
tout les objets créer et non pas pour un seul objet.
Les méthodes qui sont déclarée static sont les méthodes qui ne s'appliquent pas à un
objet. On les utilise souvent pour les méthodes non liés aux objets qui font du
traitement comme des calculs (la classe Math par exemple qui comporte ces
méthodes) ou qui affichent quelque chose.
Pour appeler les méthodes static depuis l'extérieur de la classe ou elles sont, on les
appelle en mettant en préfixe le nom de leur classe suivi du nom de la méthode.
Ex : nomClasse.nomMéthode.
On utilise également le mot clé static lors des import pour pouvoir importer que les
méthode statique, ainsi que pour pouvoir créer un raccourcis lors de l'appel (voir mot
clé import)
Si on essaye d'importer une méthode qui est une méthode non statique, on a une
erreur de compilation.
8. For
for est un mot clé qui sers à définir une boucle et est utilisé lorsqu'on connais le
nombre d'itération a faire pour le bloc d'instruction dans la boucle. Il traduit le
concept du « pour » en algorithmique, mais en plus de ceci, le for en java offre
d'autres possibilités.
Grammaire
BasicForStatement
for(ForInit(opt);Expression(opt) ; ForUpdate(opt))
Statement
ForInit
C'est la partie qui sers à initialiser la boucle, il est optionnel. On y déclare une
ou plusieurs variable qu'on va déclarer dans la boucle.
Exemple : int i = 0 ;
(int i = 1, j = 2, k = 3)
Si on ne met rien dans le ForInit mais qu'on utilise des variable dans
l'expression ou le ForUpdate qui n'ont pas été déclarée, erreur de compilation. A
noter que si les variables ont été déclarée avant le ForInit, alors cela compilera et la
boucle se lancera normalement, le ForInit pourra être vide dans ce cas là. Si il n'y a
pas de variable utilisée dans l'expression ou le forUpdate ou l'Expression alors le
ForInit peut être vide, cela compilera mais il y'aura une boucle infinie.
Expression
C'est une expression de type booléene, qui est soit vraie soit fause et qui est
utilisée pour stopper la boucle. Il est optionnel.
Ex : a < 10
a≥b
Quand on l'oublie, il n't a pas de condition pour stopper la boucle, du coup, boucle
infinie.
ForUpdate
Le forUpdate est utilisé pour mettre à jour les indices du ForInit car
l'expression va être restesté par la suite et le résultat peut-être changé en fonction de
l'évolution du compteur. Il est facuitatif. On y trouve les pré/posty incrémentation et
pré/post décrémentation. Il peut également contenir une assignation ou un appel de
méthode.
Statement
A noter que toute variable initialisée dans la boucle est inutilisable en dehors.
On peut arrêter une boucle en utilisant un break pour stopper avant la fin, de même
qu'on va réintérer une boucle grâce à continue.
On utilise les for étiqueté pour utiliser le break et sortir de plusieurs boucle grâce a
un label.
Ex de for:
9. Foreach
Grammaire
EnhancedForStatement
Type
Les différents type comme int, byte, short, String, boolean etc. Doit être
du même type que ce qui compose l'élément a parcourir sinon erreur de compilation.
(Donc pour un tableau 2D, vu qu'il est composé de tabbleau d'élément, il faudra qu'il
soit un tableau d'élement, ensuite, on refera un foreach pour parcourir le tableau a
une dimension
Identifier
Expression
A noter qu'on ne peut pas avoir accès au compteur dans le foreach, ni aux indice et on
ne peut pas modifier le contenu de l'élément Iterable dans le foreach.
L'ordre dans lequel on va parcourir les éléments est l'ordre de l'élément en partant du
début.
Exemple
String [] s = new String [4] ;
for(String sa : s ) {
system.out.println (« sa ») ;
}
Exemple2
ArrayList<Element> element = new ArrayList
for (Element element : elements) {
system.out.println(element) ;
}
Exemple 3
Incrémentation
post Incrémentation
exemples :
1)
i=5;
j = i++ ; // j = 5 ici car on assigne j = i avant d'incrémenter.
2)
int b = 5
int c = 5
i = c++ + b ++
// ici i = 10 car le premier opérande vaudra 5, l'incrémentation se faisant au
moment du '+' dans le calcul ( à la fin de l'expression c++), donc cela fait 5+5
i=c+b
// maintenant i = 6+6 = 12 car les deux variable ont été incrémentée
pré Incrémentation
Exemples :
1)
int i = 5
j = ++i ; // ici j = 6
2)
int i = 12 ;
i = ++i + ++i // ici i vaut 13 + 14 donc 27.
Décrémentation
pré décrémentation
Exemple
int i = 6 ;
int j = --i // i vaut 5
post décrémentation
Exemple :
int i = 12 ;
int j = i-- ; // j vaut 12
Exemples généraux :
- int i = 5
i = i++ + ++i // i vaut 5 + 7 donc 12
- int i = 2
f(i++, --i) // f(2,2)
int i = 2
f(--i, i++) // f(1,1)
11. Final
Le mot clé final indique qu'un élément ne peut-être modifié dans la suite du
programme et que c'est une constante d'un certain type. Il peut s'appliquer aux
méthodes et attributs d'une classe.
Par convention, les variables notée final sont écrite en majuscules (en séparant les
mots par des underscore).
Exemple :
Si on mer final devant le nom de la classe, la classe ne pourra pas être utilisée pour
l'héritage.
Exemple :
La méthode sera inchangée dans le cas de l'héritage et la classe fille (qui a héritée) ne
pourra pas modifier cette méthode dite final
Pour l'utilisation, on utilise les constantes car on veu parfois qu'une variable reste
constance ertt qu'elle ne subisse aucune modification. Cela est également utile
lorsqu'on veut changer la valeur de cette constante car on a que la déclaration a
modifier.
Exemple de final :
final int X = 2 ;
X=3; // erreur de compilation (RuntimeException)
12. Expression-instruction
Grammaire
ExpressionStatement
StatementExpression ;
StatementExpression
Assignment
PreIncrementationExpression
PreDécrementationExpression
PostIncrementationExpression
PostDécrementationExpression
MethodInvocation
ClassInstanceCreationExpression
Assignment
C'est une expression ayant une valeur et un type, la valeur est la valeur de la
variable et le type est le type de la variables
LeftHandSide
Identifier
ArrayAccess
Ex : element[i] ou a
AssignmentOperator
= *= /= %= += -=
Ex : int somme = 2 ;
somme += 1 // somme = somme + 1
On ne l'utilise pas seulement pour des entiers, cela marche également avec des
char
Ex : i = 2 ; ---> OK
i = i = (i*=2) + 1 ---> OK
L'appel de méthode est une expression ayant un type (le type de retour
de la méthode) et une valeur (celle retournée par la méthode).
Instanciation de classe
Créer une instance d'une classe est une expression, elle a un type (celui
de l'objet crée) et une valeur (la référence vers l'objet, l'adresse).
Dès qu'on crée un objet, il va directement sur le tas, si on ne le référence plus (via
son adresse- alors le garbage collector va libérer l'adresse mémoire de l'objet.
Pré/Post inc/Décrémentation
voir le 10.
13. Encapsulation
Cela permet donc de contrôler ce à quoi les autres classe auront accès. On donne
accès juste à ce qui est nécessaire et pas plus. Par exemple, on ne va pas mettre
d'accesseur pour des attributs non utilisé ailleurs que dans la classe elle même.
On déclare généralement les attributs private auxquels on aura accès grâce aux
accesseur (getter) et mutateur (setter). Les méthodes utilisés sont elles déclarée
comme public. On utilise donc la visibilité pour pouvoir régler l'encapsulation.
Setter : Leur but est de modifier les attribut via une valeur reçue en paramètre
exemples :
14. While
Grammaire
C'est dans le Statement qu'on trouve l'incrémentation qui est optionnelle (si
elle n'y est pas, boucle infinie). Contrairement au for, la déclaration de la variable
qui s'incrémente ne se fait pas dans le while mais avant. L'incrémentation doit
également avoir une influence sur l'expression booléene afin d'éviter les erreurs du
type RunTimeException lorsque, par exemple, on dépasse un tableau.
Exemple :
while(Expression) {
Statement
ForUpdate
}
Dowhile
Grammaire
int i = 9 ;
do {
i+=1 ;
} while( i == 10) ;
15 .Throws/throw
Le mot clé throw permet en java de lancer une exception . Une exception surviens
lorsqu'une erreur est détectée, comme par exemple lorsqu'on ouvre un fichier qui
n'existe pas ou lorsque l'utilisateur entre des données incorrecte.
Dès lors on peut se demander pourquoi jeter une exception. Une exception est jetée
lorqu'on vérifie les contraintes liés a une partie du code et lorsque cette contrainte
n'est pas respectée. Par exemple si on demande a l'utilisateur d'entrer un nombre
positif et qu'il entre un nombre négatif on peut choisir de lancer une exception dès la
détection du problème afin que cette erreur ne se propage pas dans le reste du code.
L'Exception est un objet qui fait parti est objets dis Throwable 'Jetable' en français,
Throwable est une classe sous-classe de la classe Object et qui est chargée de traiter
les erreurs. Vu que ce sont des objet il faut créer l'objet afin de pouvoir le jeter et c'est
pour cela qu'on utilise
On créer un nouvel objet Exception auquel on envoie le message qui est la raison afin
de créer cet objet. Il faut savoir qu'on peut créer ses propres exception en utilisant la
notion d'héritage. On crée une classe avec un nom d'exception qu'on fait hériter de la
classe Exception en utilisant le mot clé extends. Le constructeur de cet objet fait
appel au constructeur du parent via « super » en lui envoyant le message qui sera
affiché lors de l'exception, mais on peut aussi ne pas mettre de message, ce n'est pas
obligatoire
La classe Error représente une erreur grave qui provoque l'arrêt de la machine
virtuelle Java, on ne s'en releve pas.
La classe Exception représente d'autres erreur qui sont soit des erreurs personnalisées
comme vu ci-dessus, des erreur du type RuntimeException (qui sont directements liés
a l'incompétance du programmeur comme par exemple NullPointerException ou
ArrayOutOfBandException) ou les deux (des exception créer qui héritent de
RuntimeException).
Si on ne le précise pas, le compilateur nous dis que nomException doit être attrapée
ou qu'on doit utiliser le mot clé throws dans l'entête. Ce mot clé indique qu'il est
possible que la méthode lance cette exception. On dis que l'expression est relancée
Pour les expression dites CheckedException, ce sont les exception qui doivent être
contriôlée par le compilateur, il y'a des stratégie de gestion car ces exception doivent
être gérées. On peut jeter l'exception via un throw ou un try-catch ou encore une autre
statégie de gestion (que j'ai pas noté) ainsi que combiner les deux stratégie.
Exemple
16. Enumeration
Une énumération est un ensemble fixe (et petit) de valeurs sémantiquement lié.
Quand on a peu de valeurs, il est conseillé de déclarer une énumération.
L'énumération agis comme une classe car elle peut avoir des attribut et des méthodes
comme une classe, mais elle a également d'autres fonctionnalité comme le fait que les
valeurs de l'énumération sont convertis automatiquement en chaîne. Il peut aussi
apparaître dans un switch ou encore fournir un tableau avec les valeurs de
l'énumération ( via values()). Les énumération héritent de java.lang.Enum
Grammaire
EnumDeclaration
EnumBody
EnumConstants
EnumConstant
EnumConstants, EnumConstant
Ce sont les valeurs que peuvent prendre l'énumération, il peut en y avoir aucune ou
autant qu'on veut, cela compile.
EnumConstant
Identifier c'est le nom de la valeur que peut prendre l'énumération. Arguments c'est
les paramètres que peuvent prendre l'énumération (ils doivent être entre parenthèse),
car l'énumération peut contenir un constructeur et des attributs pour chaque valeur,
elle peut aussi en avoir aucun, cela compile. ClassBody c'est le reste de la classe.
EnumBodyDeclarations
; ClassBodyDeclarations(opt)
Une fois que toutes les valeurs que peut prendre l'énumération ont été déclarés, il faut
mettre un ;, sinon erreur de compilation, on pourra continuer d'écrire la classe avec un
ClassBodyDeclarations ou par exemple il y'aura un constructeur et des méthodes
pour l'énumération, on peut aussi ne rien mettre.
Par convention, on met les valeurs de l'énumération en majuscule car ce sont des
valeurs constantes.
Exemples :
Il existe des méthodes propre aux classe enum. C'est le cas de values() qui renvoie un
tableau a une dimension avec toutes les valeurs de l'énumération. C'est assez pratique
pour la parcourir avec des foreach.
et le constructeur :
et la méthode
Copie Superficielle
On peut l'effectuer via une simple assignation. Imaginons des objets Personne ayant
un attribut « nom ». Grâce a cette copie, les deux objets pointent vers la même
référence en mémoire, mais si on modifie personne1, alors personne2 sera également
alteré, si on modifie la copie, l'original sera également altéré.
On peut également faire une copie superficielle avec la méthode clone() de la classe
Object. L'utilisation de cette méthode est déconseillée car elle est mal concue. Cette
méthode peut convenir pour créer faire une copie d'attributs de type primitifs ou
immuables (qui ne changeront pas), si on a des attributs mutables, il faudra procéder
à la réécriture afin de pouvoir eux même les cloner (la classe qui contiens l'overriding
implémente l'interface Cloneable).
Dans le cas des tableaux, lorsqu'on clone un tableau a une dimension, il n'y a pas de
problème, par contre, dans le cas de tableaux a plusieurs dimension, seul le premier
tableau est cloné… C'est l'une des raisons pour laquelle clone() est déconseillé, il
faudra donc procéder a un overriding avant de l'utiliser pour pouvoir cloner le
tableau.
Pour les copies de tableau, on peut également utiliser une méthode de la classe Arrays
qui se nomme copyOf() qui permet de copier tout le tableau ou une partie (et qui
completera la partie manquante du tableau par des null. A noter que si l'on modifie le
tableau original par la suite, le tableau copié sera également modifié.
Exemple copyOf :
String [] afou = Arrays.copyOf(fayen, fayen.length);
Copie profonde
Pour les objets on utilise une technique qui se nomme « constructeur par copie » afin
de recréer un objet ayant une autre référence mais les même caractéristiques que
l'original. On le fait en créant un second constructeur dans la classe de l'objet qu'on
veut copier. Ce nouveau constructeur reçois l'objet à copier en paramètre et crée un
nouvel objet avec les même caractéristiques.
Exemple :
Ainsi les références ne seront plus les mêmes et si on altère l'original, la copie reste
intact.
On peut l'effectuer pour les tableau et les tableaux a plusieurs dimensions via la
méthode copyOf() à laquelle on rajoutera ce concept de constructeur par copie. En
effet, on crée un nouvel objet ayant seulement la longueur du premier tableau, ensuite
on fait une boucle qui utilisera copyOf() pour copier chaque tableau de tableau et
ainsi éviter tout problèmes.
Exemples :
Pour les tableaux, on peut également faire des copie profondes avec deux boucles for,
c'est fastidieux mais c'est une copie profonde et on ne rencontrera pas de problèmes.
Pour les tableaux, on peut également mélanger les deux méthodes, celle des boucles
et du constructeur par copie. Cette technique sera très serviable pour les tableaux
d'objets, afin de faire une copie profonde et sans risque, on nomme cela la copie
profonde défensive.
Exemple :
Les mots clé try et catch sont utilisés pour traiter et gérer les exceptions qui peuvent
survenir dans un programme. Globalement, l'instruction try-catch se présente comme
ceci. On met les instructions qui peuvent mal se passer dans le bloc try{}et si une
exception surviens, il y'a dans le catch {} les instructions va régler le problème. Ces
deux mots clés sont indissociables les uns des autres, il ne peut y avoir de try sans
catch et inversément.
Exemple :
int a = 100 ;
try {
int b = scanner.nextInt() ;
int c = a/b // si on a rentré 0, il y'aura une exception car on ne peut pas
diviser par zéro
} catch(Exception e) {
system.out.println(« Division par 0 impossible ») ;
}
Quand une instruction se passe mal dans le try, le code du try est interrompu, et le
code du catch est exécute. Une fois que le code du catch est terminé, on exécute la
suite du programme qui était après le bloc try-catch.
On remarque que pour le catch, il faut définir le type et le nom de l'exception qui
pourra être attrapée. En ne précisant pas et en mettant Exception, on est certain que
tout type d'Expression sera catché car toutes les exceptions héritent de la classe
Exception. Mais on peut également choisir de n'attraper que les
IllegalArgumentException, les QuartoException(si elle a été crée) ou d'autres types
d'exception, pour ce faire il suffit simplement de modifier les parenthèse qui suivent
le catch.
Exemple
try {
…
} catch (IllegalArgumentException argu) {
…
}
Etant donné que l'Exception est un objet, elle a des méthodes. Pour pouvoir utiliser
les méthodes de l'Exception comme par exemple getMessage(), on utilise :
Identifier.MethodName() ;
Un try peut avoir plusieurs catch afin de catcher plusieurs exception et reserver un
traitement spécial à chacune des exception. L'ordre ici est très important car il faut
commencer par le plus pertinent jusqu'au moins pertinant.
Ex :
try {
…
} catch(IllegalArgumentException e) {
…
} catch(QuartoException ex) {
…
}
Quand le traitement à faire est le même pour plusieurs types d'expression qu'on veut
catcher, on peut utiliser les catch multiples avec l'opérateur | pour déterminer séparer
les type d'Exception.
Ex :
try {
…
} catch(QuartoException | IllegalArgumentException e) {
…
}
On remarque qu'il n'y a qu'un seul Identifier qui est déclaré a la fin de la parenthèse.
En fonction de l'exception qui est catchée en premier, les méthodes renverront un
résultat différent.
Finally
Le mot clé finally consiste à exécuter une partie de code quoi qu'il arrive, même si
l'exception surviens dans le try et que le try est interrompu ou même en cas
d'instruction break ou continue, la partie du code dans la clause finally sera exécutée.
finally n'est pas indépendant, il doit être accompagné d'un try et donc d'un catch, il
peut se placer avant ou après le catch. Ce mot clé est utilisé pour libérer les
ressources. Les ressources sont des objets qu'on peut ouvrir et qu'on doit fermer
lorsqu'ils ne sont plus utilisés, comme par exemple des flux. Avant ce moyen était le
seul pour pouvoir s'assurer que ces ressouces allaient se fermer normalement.
Maintenant il existe une alternative pour pouvoir fermer ces ressources quoi qu'il
arrive. On l'appelle try-with-ressources.
Exemple de finally :
try {
…
} catch(Exception e) {
….
} finally {
flux.close()
}
Les try with ressources permettent de déclarer une ou plusieurs ressources, une
ressource est un objet ayant besoin d'être fermé lorsqu'il n'est plus utilisé. Grâce au
try with ressources, on est assuré que chaque ressource sera fermée lorsqu'elle ne sera
plus utilisée. Il n'est plus nécessaire de fermer les ressources grâce a la méthode
close() et il ne faut pas le faire.
Les ressources qui seront fermées se trouveront dans une parenthèse qui suis le try.
On peut toujours utiliser des clause finally mais la fermeture des ressources se fera
avant l'execution de ces clauses. A noter qu'il est obligatoire de définir les ressources
a fermer dans les parenthèses qui suivent le try, sinon, erreur de compilation.
Exemple :
03.FileReader("C:/Users/jm/AppData/Local/Temp/monfichier.txt")
)) {
A la fin du bloc la ressource bufferedReader sera donc fermée sans qu'on ait besoin
d'utiliser la méthode close(). La ressource sera fermée a la fin des instruction, qu'elles
se soient bien passé (fin du try, pas besoin d'aller dans le catch) ou mal
passée(passage par le catch).
19. Héritage
Pour cela on utilise le mot clé extends qui va suivre le nom de la classe mère dans
l'entête comme ceci :
Les attributs et les méthodes de la classe mère doivent être visible dans la classe fille.
Pour cela aux lieux de mettre les champs private on les met protected, ainsi ils seront
visible dans la classe fille.
L'overriding est le fait de réécrire une méthode afin qu'elle puisse nous rendre service
pour la classe fille car celle de la classe mère est obselète pour la classe en question.
Imaginons le cas de la méthode toString() de la classe mère qui avait été définie. Si
on rajoute un attribut et qu'on voudrait l'inclure dans le toString(), il faudra réécrire la
méthode et rajouter ce qu'on veut à la méthode, ainsi la méthode de la classe mère est
ignorée au profit de la méthode qui a été réécrite.
Toutes les classes dans le langage java héritent d'une classe qui est la classe Object, la
seule classe qui n'hérite d'aucune autre classe c'est Object. La déclaration est
implicite, nous n'avons pas besoin de faire a chaque fois extends Object mais si nous
le faisons ça ne change rien.
Ex :
public class Board ---> public class Board extends Object
Donc toute les classe en java héritent de Object et des méthodes qui lui sont propre.
Une classe qui est dites final ne pourra pas avoir de classe fille et faire hériter, même
si elle même peut être la classe fille d'une classe non final. Une méthode final est une
méthode qui ne pourra être réecrite dans la classe fille.
L'héritage inclus également un autre mot clé super qui fait référence à la classe
parent. Ainsi on pourra l'utiliser dans le constructeur de la classe fille pour créer un
objet via super(param) ou faire appel aux méthodes ou aux attributs de la classe mère
via super.nomMéthode() ou super.nomAttribut.
En Java, on ne peut hériter que d'une seule classe a la fois(hormis l'héritage implicite
de Object). Mais la solution pour remédier a ce problème c'est d'implémenter
plusieurs interfaces via le mot clé implements. En effet, une interface peut hériter
d'autant d'interface qu'elle veut via extends et on peut implémenter autant d'interface
qu'on veut. A l'inverse, une classe peut avoir une infinité de classe fille.
Exemple :
On ne pourra pas instancier un objet de la classe fille avec la classe mère, par contre,
on peut instancier un objet de la classe mère avec la classe fille, mais les attribut et
les méthodes de la classe fille ne seront pas accessible pour cet objet de la classe
mère. Pour instancier un objet de la classe fille avec la classe mère on peut tenter de
faire un cast, il n'y aura pas d'erreur de compilation, mais il peut y avoir une
exception a l'exécution.
Exemple avec Chomeur qui hérite de Esi
L'héritage est également utilisé avec un autre concept, celui des classes abstraites.
Une classe abstraite est une classe qui ne peut pas produire d'instances, a l'inverse des
classe concrète vues jusqu'à là. Ceci implique donc que ces classes abstraites ne sont
utilisés que par leur classe fille.Pour les déclarer, une utilise le mot clé abstract. Le
rôle de ces classe est la factorisations des fonctionnalités commune a plusieurs classe.
Par exemple, si je sais que dans une classe Triangle et une classe Rectangle je vais
devoir utiliser une méthode qui déplace les coordonnées et que le mécanisme est le
même pour les deux classe, je peux créer une classe abstraite dont vont hériter les
deux classes Rectangle et Triangle afin de pouvoir avoir moins de code a écrire, cela
simplifie donc l'écriture.
Exemple d'héritage
20. Instanciation
Une instance d'une classe est un objet avec un état, déterminé par la valeur de ses
attributs, et un comportement qui dépends de la valeurs de ses attributs vis a vis d'une
méthode. Une instance d'une classe est un exemplaire de la classe ayant les mêmes
caractéristiques. On appelle plus communément l'instance d'une classe, un objet. Une
classe peut avoir autant d'instance qu'on veut.
TypeObjet nomObjet ;
TypeObjet est le nom de la classe, le modèle de l'objet qu'on va créer, l'objet est le
nom qu'aura réelement l'objet lorsqu'on fera appel a lui pour l'utiliser. On remarque
que la déclaration ne se fait pas comme avec les type primitifs prédéfinis mais avec
un type référence, car les objets sont, comme les tableaux, des type référence.
L'instanciation est donc séparée en deux étapes, l'utilisation du new qui va réserver
l'espace mémoire pour contenir l'objet et l'initialisation de l'objet via le constructeur
en lui fournissant (ou non, dépends du constructeur) des paramètres afin qu'il puisse
fixer l'état de l'objet avec les paramètres qu'on lui donne (ou non). Ainsi, on aura
créer un nouvel objet sur le tas.
Exemple d'instanciation :
Une fois que ceci est fait, l'objet existe réelement sur le tas et on pourra alors l'utiliser
et utiliser ses méthodes ou ses attributs afin de procéder au traitement voulu.Les
instances d'une classe sont indépendantes l'une de l'autre sauf si il y'a un membre
statique, dans ce cas là, toutes les instances de la classe partagent le même membre.
21.Instanceof
But : Tester si un objet passé en paramètre est une instance d’une classe déterminée et
retourne une valeur booléenne, true si unObjet est une instance de la classe
uneClasse, false sinon.
Exemple :
public class Point {
private int x,y;
public Point(int abs, int ord){
x = abs;
y = ord;
}
public static void main(String[] args) {
Point p = new Point(2,3);
System.out.println(p instanceof Point);
}
}
Affiche true car p appartient à la classe Point.
Autre exemple :
public class Point {
private int x, y;
public Point(int abs, int ord) {
x = abs;
y = ord;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof Point)) { //On aurait pu mettre if( o.getClass() !
=this.getClass())
return false;
}
Point point = (Point) o;
return this.x == point.x && this.y == point.y;
}
public static void main(String[] args) {
Point p = new Point(2, 3);
Point p2 = new Point(2, 3);
System.out.println(p.equals(p2));
}
}
La première chose faite est de tester si l'objet passé en paramètre est bien de la
classe Point et s’il est non nul (dans le cas contraire on retournera false). Instanceof
permettra de tester la classe d'un objet. En l'occurrence, il retourne true pour tous les
objets de la classe Point, et de toute classe qui hériterait de Point. Une fois que nous
sommes sûr d'avoir un objet Point en paramètre, alors il nous faut comparer ses
champs un par un. Pour pouvoir accéder à ses champs, il faut le convertir en objet
de la bonne classe et c’est là qu’intervient le casting ! Elle consiste à déclarer un
objet (ici point), et à lui affecter la valeur de l'objet à convertir, en mettant devant et
entre parenthèses le type dans lequel on veut faire cette conversion.
22. Le Temps :
Temps Machine :
2 classes : java.time.Instant => représente un temps machine (timestamp).
Nbres sec écoulées depuis 1janvier 1970 && Valeur stocké dans un long.
Exemple :
Exemple :
Instant instant = Instant.now() ;
Instant DeuxMinutesPlusTard = now.plus(Duration.ofMinutes(2)) ; // affiche l’heure
//actuelle avec deux minutes supplémentaires.
Voir la période entre deux moments :
Instant now = Instant.now();
Instant now1 = now.plus(Duration.ofHours(5).plusMinutes(4));
Duration dur = Duration.between(now, now1);
System.out.println(dur) ; // représente une période sous la forme iso8601.
Temps humain :
Exemples :
//On affiche premièrement une date (ici l’année de naissance où Month est une
//enum)
//On affiche ensuite seulement le jour de la semaine de cette naissance.
//Et ensuite on fait un affichage sous le format DateTimeFormatter (en français
//ici).
//Pour mettre sous un format anglais on rajoute alors :
System.out.println(birth.format(form.withLocale(Locale.ENGLISH)));
Duration, qui représente une durée en millisecondes, souvent récupérée à partir d’un
intervalle.
Period ne représente pas une durée de longueur fixe et bien définie entre deux points
dans le temps, mais une durée conceptuelle "flottante", de durée réelle variable (ex:
un jour, un mois, un an...). Cela permet d'effectuer des calculs assez naturels comme
"ajouter un mois", indépendamment du nombre de jours réel par mois.
23.Méthode :
C’est une boîte noire définie par un nom et un ou plusieurs paramètres, qui en fin
d’exécution fournit un résultat qui varie selon la valeur du ou des paramètres.
Java propose des méthodes prédéfinies, mathématiques ou non, très utiles.
Pour appeler une méthode qui se trouve dans une autre classe :
NomClasse.nomMethode();
Le type et l’ordre des paramètres doivent être respectés, sous peine d’une erreur de
compilation. Dans le cas où la méthode possède plusieurs paramètres, ceux-ci sont
séparés par des virgules et devant chaque paramètre, est placé son type, même si deux
paramètres consécutifs possèdent le même type.
Le nom de la méthode est choisi en fonction à pouvoir représenter ce qui sera réalisé
par son intermédiaire, et est écrit en minuscule sauf pour les initiales de chaque
nouveau mot.
Remarque : On peut avoir plusieurs méthodes du même nom mais alors avec des
arguments différents !
24.Constructeur
C’est une méthode sans valeur de retour qui est utilisé pour initialiser les données
d’un objet au moment de sa déclaration en mémoire et de le créer.
Les constructeurs portent le même nom que la classe où ils sont définis et peuvent
avoir un nombre quelconque de paramètres. S’il n’y a aucun constructeur, java
propose un constructeur par défaut qui est initialisé à 0 ou à null en fonction de ses
données ( Possibilité d’avoir plusieurs constructeurs dans une même classe à
condition que les paramètres soient différents).
Il est possible de faire appel à un constructeur se trouvant dans la même classe par le
mot clé this.
Exemple :
Il est également possible de faire des tests de validité sur les paramètres entrés
dans le constructeur pour s’assurer que l’objet se créée dans un été valide.
Utilisation d’un if par exemple pour voir si un nombre n’est pas inférieur à 0.
25.Package
Groupement de classes Java. Le package détermine où le byte code est cherché (le
.class). L’attribution d’un nom de package se fait au niveau du fichier source, en tout
début de fichier, comme ceci :
package nomPackage ;
Pour utiliser une classe appartenant à un package il est important de fournir son nom
qualifié (cité son nom de package avec son nom de classe), comme ceci :
nomPackage.nomClasse
Il est également possible d’accéder aux classes d’un package faisant partie d’un
package différent par un import de ce package :
Pour que le compilateur puisse trouver un package, Java utilise une variable
d’environnement appelée CLASSPATH donnant la liste des chemins d’accès aux
classes.
Exemple :
On crée une classe Test dont le package est package g39753.quarto.view;
Si une classe ne possède pas de package, le compilateur considère que les classes
appartiennent au package par défaut (pas besoin de spécifier le chemin d’accès).
Il existe aussi un paquetage particulier appelé java.lang qui est importé
automatiquement par le compilateur. Ce qui permet d’utiliser les classes standards
telles que Math,System,.. Sans devoir importer un package dans le fichier source.
26.This/Super :
Exemple :
On peut également utiliser this comme un nom de méthode au sein d’un constructeur
pour appeler un autre constructeur de la même classe.
Exemple :
On peut également faire appel à une méthode de la classe dans le constructeur avec le
mot clé this.
Exemple :
Super :
Exemple :
public class A {
public getA(){..}
}
Remarque : Lorsqu’une classe hérite d’une autre, dans le constructeur enfant, super
est appelé implicitement (s’il n’est pas présent) pour faire appel au constructeur
parent sans paramètre, sauf s’il existe un constructeur avec paramètre dans le parent.
public class A {
public int nb ;
public A (int nb) {
this.nb = nb ;
}
}
Une interface est définie au sein d’un fichier qui porte son nom suivi de l’extension
.java. Le terme interface remplace le terme class. Les comportements proposés par
l’interface sont définis à partir des en-têtes de méthodes uniquement (signature).
- Toutes les méthodes d'une interface sont implicitement abstraites (cf. abstract) on
n’a pas besoin de mettre abstract devant le nom de la méthode.
- Une interface peut être étendue par une ou plusieurs autre(s) interface(s).
- Une interface peut hériter d’une autre interface (avec extend pas implements !!).
- En fait, une interface est une classe abstraite dont toutes les méthodes sont
abstraites et dont tous les attributs sont des constantes (cf. final).
Une fois l’interface définie, les méthodes sont concrètement décrites au sein des
différentes classes qui implémentent l’interface.
2) Exemples
Dans ce cas v et t sont vus comme des Vehicule et donc on ne peut appeler sur ces
objets que les méthodes définies dans l'interface Vehicule !!
Exemple 2 :
Interface Comparable
TypeTableau [] nomTableau ;
nomTableau = new TypeTableau [tailleTableau] ;
• TypeTableau peut être aussi bien un type simple (int, double,...) qu’un type
référence. Dans ce cas, le tableau est un tableau d’objets stockant dans chacune de ses
cases l’adresse d’un objet à mémoriser.
• L’opérateur new réserve autant de cases mémoires consécutives qu’il est indiqué
entre les [], soit tailleTableau. L’opérateur new détermine enfin l’adresse de la
première case du tableau et la stocke grâce au signe d’affectation, dans la case
nomTableau créée à l’étape précédente.
b. Les tableaux sont des objets. Les objets sont caractérisés par leurs données et les
méthodes qui leur sont applicables. Exemple : .length
2) Exemples
Les éléments d’un tableau sont indicés à partir de 0. Chaque élément peut être accédé
individuellement en donnant le nom du tableau suivi de l’indice entre [ ]
Chaque indice étant contrôlé par une boucle for, la technique consiste à imbriquer les
deux boucles.
2) Exemples :
int [][] test = new int [2]; // Ne fonctionne pas car tu déclares un tabeau multi-
dimension et tu ne donne la taille que d'une dimension.
int [][] entierss = new int [] {1,2}; // Ne correspond pas à la grammaire java, il faut
faire : int[][] entiers = {{1}{2}};
int [][] entiserss = new int [] {{1},{2}};// Aurait pu fonctionner si on avait déjà
déclaré un tableau avant int [][] entiserss = {{5,8,6,0,7},{3,3,2}};,
//et si on avait mis deux paires de crochets vu que c'est deux dimensions.
int [][] salut = new int [2][3]{3,2};// Ne fonctionne car on ne donne pas la taille et les
valeurs en même temps. c'est l'un ou l'autre.
int [][] salut = new int [2][3]{null,null};// Ne fonctionne car on ne donne pas la taille
et les valeurs en même temps. c'est l'un ou l'autre.
30. I/O(Codage, fichier)
1.Codage
La taille du fichier vaut un byte (représenté par les 7 derniers bytes) parce que
la valeur 32 est codée sur 8 bits donc 1 byte.
0000000 3332 0000002 cette fois ci la valeur n'est pas la même, tout
simplement parce que ce sont les valeurs unicode de '3' (33) et '2' (32)qui sont
codés dans ce fichier, la taille est plus grande car chaque caractère est codé sur
8 bits (UTF-8).
Il y'a une spécificité par contre dans le codage en texte, en effet quand on code un
caractère spécial (on dira qu'il est étendu, voir Unicode), on verra que la taille pourra
faire par exemple 2 bytes voir plus alors que ce n'est qu'un seul caractère. Prenons par
exemple le caractère œ. Son codage se fera ainsi :
On voit bien que le fichier fait 2 bytes, c'est normal car la valeur 93c5 est codé
sur 2 bytes, mais 93c5 ne correspond pas a la valeur 0153 dans la table unicode
qui correspond a ce caractère. Tout simplement parce qu'on a appliqué un
masque sur le codage de 0153, voici un exemple.
2. les Fichiers
En Java, les fichiers sont considérés comme des flux dans lesquel on pourra lire ou
écrire, ces flux peuvent être binaire ou texte. Ces flux sont uniformes et ils sont non
structurés.
Java fournis des classes de bas niveau pour pouvoir lire/écrire des byte (binaire) et
des char(texte), il existe également des classe de haut niveau qui permettent de
lire/écrire des objets et des lignes entière de texte.
Intéressons nous aux classes de bas niveau. Il y'a 4 classes principales pour les
classes de bas niveau
Byte (8 bits) Char (16 bits
Lire (READ) InputStream Reader
Ecrire (WRITE) OutputStream Writer
Mais il n'y a pas que ces classes, en effet pour chaque classes on aura des sous-
familles comme par exemple FileInputStream ou FileWriter.
Par exemple pour la lecture binaire, on utilisera InputStream qui contiens des
méthodes permettant de lire des bytes. Pour instancier l'InputStream on utilise une
classe utilitaire nommée Files qui contiens une méthode newinputStream qui renvoye
un input stream sur le fichier qu'on veut lire. Cette méthode a besoin d'un Path (voir
l'autre mot IO) et d'une option d'ouverture pour pouvoir ouvrir le fichiers, ces options
sont contenues dans l'Enumeration StandardOpenOption par exemple qui contiendra
READ, APPEND, CREATE ou encore WRITE. Voici un exemple de lecture dans un
fichier binaire :
int b;
try (InputStream in = Files.newInputStream(Paths.get("File"),
StandardOpenOption.READ)) {
b = in.read();
while (b != -1) {
System.out.println(" " + b);
b = in.read();
}
} catch (IOException e) {
System.out.println("problème");
}
On remarque également l'utilisation d'un try with ressources (voir mot clé try) et des
IOException, en effet, on est dans le package java.io et toutes les classes comme
Files, InputStream, IOException, StandardOpenOption en font également partis.
Pour l'écriture binaire dans un fichier le principe est le même sauf que cette fois ci on
utilise OutputStream pour écrire dans un fichier binaire. On utilise également une
méthode des Files qui renvoie un output stream et par contre l'option d'ouverture
change, au lieu de lire on peut créer un fichier pour y écrire ou tout simplement écrire
directement. Voici un exemple :
int b;
try(OutputStream out=Files.newOutputStream(Paths.get("File2"),StandardOpenOptio
n.CREATE)) {
out.write(64);
} catch (IOException e) {
System.out.println("problème");
}
C’est le même principe que pour les fichiers binaire sauf que les classes sont
différentes parce que on utilise FileReader() pour lire et FileWriter() pour écrire =>
des int également mais lis ou écrit un char
Reader
Base de toutes les classes relatives à des flux texte d’entrée, dotées de fonctionnalités
de base (lecture de caractères et de tableaux de caractères)
FileReader
Fichiers texte d’entrée. Cette classe est dotée des mêmes fonctionnalités de base que
Reader.
FileReader(String nomFichier)
FileReader(File objFichier)
Writer
Base de toutes les classes relatives à des flux texte de sortie, dotées de fonctionnalités
de base (écriture de caractères et de tableaux de caractères).
int write(int n) // écrit le caractère n
int write(char[] tabChar) // écrit le tableau de caractères tabChar
void close() // ferme le flux
FileWriter
int c;
try (FileReader in = new FileReader("data")) {
while ((in.read()) != -1) {
c = in.read();
System.out.print((char) c);
// il faut faire le cast car ce qui est renvoyé par le flux, c'est un int
}
} catch (IOException IOE) {
System.out.println("salam");
}
Exemple FileWriter
int c = 'a'; // on caste car il a besoin d'un int, mais cela fonctionne si on laisse en char
try (FileWriter out = new FileWriter("fayenafou")) {
out.write(c); // seuls les 2 bits de poids faible sont écris, ceux qui correspondent
//au codage
} catch (IOException IOE) {
System.out.println("salam");
}
31. Scanner/Console
1. Scanner
C’est une classe qui offre plusieurs méthodes de lectures, écritures et de tests. On l’a
très souvent utilisé au tout début de notre apprentissage java en tapant au clavier par
exemple des valeurs, des chaines... Et aussi dans l’écriture d’un fichier Texte ou
binaire. Mais cette classe est beaucoup plus large.
- Premièrement, découper la chaîne de caractères en tokens grâce à un délimiteur ;
Il s'agit par défaut d'un caractère "blanc" (espace, tabulation, retour à la ligne...) ;
Note : lorsque sont retirés les commentaires et espaces, un programme n’est plus
composé que de tokens, qui sont donc les mots ou symboles terminaux du langage.
Elle a fait son apparition dans le package java.util dans la version 1.5.0 de java.
Exemple :
Import java.util.Scanner ;
On doit toujours l’importer car elle ne fait pas partie de java lang.
Ensuite pour l’utiliser à notre gré dans notre classe il faut implémenter un objet de
type Scanner via l’instruction:
Scanner clavier = new Scanner(System.in) ;
Utiliser une méthode de la classe Scanner afin de lire une valeur d’un certain type.
unEntier = clavier.nextInt() ; // pour lire un entier
nextLine() pour les chaines jusqu’à la fin de la ligne, next() prend tous les
caractère qu’on écrit jusqu'au prochain espace ou (retour à la ligne) et retourne un
String constitué de ces caractères.
Exemple j’écris « bonjour ça va ? »
String b = clavier.next();
b = "Bonjour" ; il ne reçoit que le bonjour
Et si j'écris "1"
Il retourne "1" mais en String
Lors de la saisie d’une valeur ne correspondant pas au type spécifié par la méthode
de lecture, une exception de type java.util.InputMismatchException sera levée.
Exemple :
String s = clavier.next(« [HhFf] ») ;
Ce qu’on doit taper c’est que les caractères H,h,F,f sinon InputMisMatchException
2) Exemple :
Flux standard
Un flux est un élément qui peut fournir ou recevoir une suite d’octets ou de
caractères. Le package java.io fonctionne avec n’importe quel flux, c’est pour cela
qu’il est aussi bien possible d’utiliser Scanner et println avec des fichiers qu’avec
l’écran ou le clavier.
Lorsqu'un programme s'exécute, 3 flux existent automatiquement et à priori
connectés au clavier et à l'écran mais peut être changé via une redirection.
- System.in : l'entrée standard de type InputStream. Classe générale pour un flux
binaire en entrée, FileInputStream hérite d’InputStream.
- System.out : la sortie standard de type PrintStream, ce qui explique l'existence de
println.
- System.err : l'erreur standard aussi de type PrintStream, Flux séparé ce qui permet
de ne rediriger que les erreurs.
System.out.println ?
C'est une classe qui fait partie du package java.io, elle permet un acc§s a la console
du système d'exploitation afin de pouvoir saisir ou afficher des données. Cette classe
fait également usage des flux de type Reader et Writer (vu dans les IO) afin de
pouvoir gérer correctement les caractères.
Pour l'utiliser, il faut donc d'abord l'importer, ensuite en créant l'instance Console de
cette manière :
Console console;
Il faudra également rajouter une méthode qui permettra d'instancier une console, cette
méthode se trouve dans la classe System et se nomme console(). Ainsi quand on
voudra utiliser une console on devra instancier comme cela :
Une fois cette étape accomplie, on a accès aux méthodes de la classe Console qui
sont assez classiques. On y retrouvera par exemple readLine() qui se chargera de lire
une ligne à partir de la console ou encore une méthode format() qui est la copie de
String.format() et qui permettra de placer un String dans le message affiché en
fonction de sa valeur. On retrouvera également une autre méthode se nommant
readPassword() permettant de lire au clavier sans afficher les caractère qu'on écris a
l'écran, souvent utilisé pour masquer un mot de passe, d'ou le nom de la méthode.
Cette méthode est donc un bon substitut a Scanner et a l'affichge via System.out, mais
le principal intérêt de la classe c'est que la lecture se fait via la console du système et
non pas depuis un IDE comme Netbeans ! On se rend compte que lorsqu'on essaye de
lancer un programme qui lis ou écris avec Console depuis Netbeans, il y'a une
nullPointerException. La seule manière d'exécuter les programmes qui fonctionnent
avec cette classe, c'est d'utiliser l'invite de commande sur Windows par exemple, ou
celui sur Linux et de lancer les fichiers via une commande java.
import java.io.Console;
public class conss {
public static void main(String[] args) {
Console console = System.console(); // on instancie via la méthode console
String name = console.readLine("Enter name");
// ici on a affiché le message en paramètre avant de lire au clavier
console.format("Your name is %s", name);
}}// ici on a affiché le message en remplaçant le %s par le paramètre name
Pour lancer ce programmes voici les étapes :
- Lancer l'invite de commande
- Aller dans le répertoire ou se trouve le conss.java et le conss.class ou juste le .java et
utiliser classpath
- utiliser la commande java conss et le programme se lance
32. Object/Objects
Object/Objects
A. Object
Object est une classe qui possède comment package java.lang (qui elle-même
contient énormément de class qui sont fréquemment utilisées comme : Math,
String, Enum... et autres).
Etant une classe elle possède donc des attributs et des méthodes, cependant
Object est une classe particulière, on dit qu’elle est la racine de la hiérarchie des
classes, c’est-à-dire que toutes les classes possèdent comme super class, la class
Object et donc ses méthodes, c’est une espèce d’héritage implicite, par défaut
toute classe hérite de Object.
C’est le boss !
Donc écrire :
class Othman extends Object {
// bla bla bla
}
est inutile !
Méthodes d’Object
1 toString ()
2 getClass ()
3 equals (Object o)
4 hashCode () si pas alz avec le hashCode ne pas en parler, sauve si le
prof demande…
I. toString()
Le to string ne donne pas toujours une forme que nous souhaitons, la plus part
du temps elle renvoi des caractères peut agréable style
‘Personne@b82e3f203’(le nom de la classe, suivie de ‘@’, et une adresse en
hexadécimal, qui est l'adresse mémoire où l'objet est stocké)
Pour changer cela il faut faire un override de cette méthode. (Redéfinir le
comportement d’une méthode existante de la classe parente)
II. getClass()
Entête : public final Class getClass()
Paramètres : aucun
Retour : une instance de la classe Class
Rôle : permet d’obtenir la classe d’un objet
III. equals(Object o)
Le hashCode de la classe Object permet d’obtenir le hash code d’un objet qui
est un nombre unique associé à l’instance de cet objet(0 si l’objet est nul), par
défaut il retourne l’adresse ou est stocké cet objet en question, nombre qui sera
unique puis ce qu’on ne peut pas stocker deux objets à la même case mémoire.
Là où ça devient chiant c’est le fait qu’il y a un lien directe entre le méthode
equals et le hash code d’un objet. Car pour la méthode equals () deux objet sont
égaux si ils retournent le même hash code.
Donc faire l’override d’une méthode equals implique l’override de la méthode
hashCode, sinon bonne chance xD !
Faire l’override d’une méthode hashCode() n’est pas facile et doit respecter un
algo bien précis.
B. Objects
Hé bien Objects n’est pas ‘object ‘ prononcé à la smex ^^ , c’est bel et bien une
classe à part entière, possédant ces propres attributs et méthodes. Comme toutes
les classes, et expliqué plus haut, elle hérite par défaut de la classe ‘object’
ainsi que de quelques-unes de ces méthodes dont celles parlées plus haut.
Plus spécifiquement Objects est une classe du package java.util, possédant des
méthodes STATIC qui permettent de travailler avec des object. Elle ne peut pas
être instancié, car class final et ne possède pas de constructeur public.
Méthodes d’Objects
I. T nonNull(T obj)
Si l’objet n’est pas nul retourne l’objet sinon lance une NullPointerException.
public void setFoo(Foo foo){
this.foo = Objects.nonNull(foo);
}
III. Les autres méthodes sont celles héritées par object ou des
améliorations de celles-ci
33. Literal
En java tous les éléments se déclarent, et ils se déclarent par des types qu’on appelle
les primitives (cf. mot-clé ‘type primitif vs Référence pour plus d’infos :p).
Un literal c’est tout simplement une valeur constante affectée à un type primitif. Ça
peut donc être : un int, un char, un long, un short…
Voyons un exemple :
Exemple :
int value = 7;
int : est un type primitif (un type de donné)
value : est un nom de variable et une référence
true : est un littéral de type entier (integer literal)
Dans l’exemple ci-dessus '7’ est un literal de type entier auquel on peut accéder par
sa référence ‘value ‘.
System.out.println(value)
Notez cependant qu’un literal peut également être une valeur constante affecté à des
objects tel que ‘String’(ou n’importe quel autres objects), par exemple les string
literal existent.
Short s = 10000
int nb = 100000
En guise de conclusion on peut dire qu’un literal possède un type une valeur et une
référence vers cette valeur.
Mais il ne faut pas se contenter de ces explication et expliquer également les types
primitifs dans le mot clé suivant
1) Type primitifs
Le langage Java dispose d’un certain nombre de types de base dits primitifs,
permettant de manipuler des entiers, des flottants, des caractères et des booléens. Ce
sont les seuls types du langage qui ne sont pas des classes. Mais ils seront utilisés
pour définir les champs de données de toutes les classes que l’on peut être amené à
créer.
Ils permettent de représenter, de manière approchée, une partie des nombres réels.
Plus précisément, un nombre réel sera représenté en flottant en déterminant un signe s
(+1 ou -1), une mantisse M et un exposant E tel que la valeur s . M . 2^E représente
une approximation de ce nombre.
Le langage Java permet de manipuler des caractères représentés en mémoire sur deux
octets en utilisant le code universel Unicode.
* Le type booléen
Ce type sert à représenter une valeur logique du type vrai ou faux. Les deux
constantes du type booléen se notent true et false et sont codées sur un octet.
Chacun des types primitifs peut être "enveloppé" dans un objet provenant d'une
classe prévue à cet effet et appelée Wrapper (mot anglais signifiant enveloppeur). Les
enveloppeurs sont donc des objets représentant un type primitif.
Avantage :
* Les Wrapper peuvent être utilisés comme n'importe quel objet, ils ont donc leurs
propres méthodes.
Inconvénients :
* L'objet enveloppant utilise plus d'espace mémoire que le type primitif. Par exemple,
un int prends 4 octets en mémoire mais un Integer utilisera 32 octets sur une machine
virtuelle en 64 bits (20 octets en 32 bits).
* L'objet enveloppant est immuable, c'est à dire qu'il ne peut pas être modifié, toute
modification de sa valeur nécessite de créer un nouvel objet et de détruire l'ancien, ce
qui augmente le temps de calcul.
Un nombre entier est un nombre sans virgule qui peut être exprimé dans différentes
bases:31
2) type référence
Le nom d'une classe peut être utilisé comme un type, de sorte qu’il est possible de
déclarer une variable de type objet ou spécifier qu'une méthode renvoie un objet. Si
une variable est déclarée en utilisant le nom d'une classe comme type, cette variable
contiendra une référence à un objet de cette classe. Une telle variable ne contient
donc pas un objet réel, mais plutôt une référence à l'instance de classe, ou objet, à
laquelle la variable fait référence.
Puisque l'utilisation d'un nom de classe comme type déclare une référence à un objet,
ces types sont appelés types de référence.
Java permet également l'utilisation d'un nom d'interface pour spécifier un type de
référence. En outre, les types de tableaux (Arrays) sont également des types
référence, car le langage Java les traite comme des objets.
Ex :
String s = "Chaine de caractères"; (sorte de tableau de caractères).
Conclusion :
Type primitif = sa valeur sur la pile
Type référence = l’adresse de l’objet est sur la pile est le contenu de la variable
(objet) est sur le tas.
« Derrière » une variable se cache une petite zone de la mémoire de l’ordinateur dans
laquelle sera stockée la valeur de la variable. Les d´déclarations sont le moyen de dire
à JAVA de réserver une zone pour chaque variable (la taille de la zone d´dépendra du
type de la variable : pour le type char, c’est 1 octet, pour le type int, c’est 4 octets,
pour double, c'est 8 octets…). »
35. toString()
Méthode héritée de la classe Objet en conséquence toutes les classes Java en hérite.
La méthode toString() définie dans la classe Object ne fait pas grand-chose : elle
renvoie le nom de la classe de l'objet concerné suivi de l'adresse de cet objet.
Lorsqu'on écrit une classe, il peut être très utile de redéfini la méthode toString() afin
de donner une bonne description des objets de cette classe. Si on l’a redéfinie (retaper
en fonction de la classe) la méthode toString() en java permet de donner un aperçu
d'un objet instancié. C'est à dire que cette méthode va retourner une chaine de
caractère représentant un objet : affichage de la valeur des propriétés par exemple.
Il est intéressant de noter que le nom de classe est bien le nom de la classe
correspondant à l’objet référencé, même si toString n’a pas été redéfinie. En effet, la
méthode toString de la classe Object utilise une technique dite de "fonction de
rappel". Plus précisément, elle appelle une méthode getClass (introduite
automatiquement par Java dans toutes les classes via le package java.lang) qui fournit
la classe de l’objet référencé sous forme d’un objet de type Class contenant, entre
autres, le nom de la classe.
class Point {
private int x, y ;
public Point(int abs, int ord) { // constructeur à 2 paramètres
x = abs ;
y = ord ;
}
}
public class ExempleToString {
public static void main (String[] args) {
Point a = new Point(1, 2);
Point b = new Point(5, 6);
System.out.println("a : " + a.toString()) ;
System.out.println("b : " + b.toString()) ;
}
}
a : Point@fc17aedf
b : Point@fc1baedf
Les objets appartenant à la catégorie List sont, pour simplifier, des tableaux à
agrandir à l’infinie. On y trouve les objets Vector (jamais vu), LinkedList et
ArrayList. On peut y insérer autant d'éléments que l’on le souhaite sans craindre de
dépasser la taille de notre tableau. Ils fonctionnent tous de la même manière : on peut
récupérer les éléments de la liste via leurs indices. De plus, les List contiennent des
objets. Un indice géré par l’interpréteur permet de retrouver l’information.
Indépendamment de cet ordre naturel, on pourra, dans certains cas, avoir besoin de
classer les éléments à partir de leur valeur. Lorsqu’il est nécessaire de disposer d’un
tel ordre sur une collection, les méthodes concernées considèrent par défaut que ses
éléments implémentent l’interface Comparable (java.lang.Comparable) et recourent à
sa méthode compareTo.
Les données enregistrées dans une ArrayList sont en réalité rangées dans un tableau
interne créé par l’interpréteur. La taille de ce tableau est gérée automatiquement par
Java. Ainsi, lorsque la liste des éléments à ajouter dépasse la taille du tableau interne,
un nouveau tableau est créé et les anciennes valeurs y sont copiées.
Implémentation :
Tous les éléments d’une même liste sont donc de même type T.
Ainsi déclaré, liste est un objet de type ArrayList, auquel on peut appliquer des
méthodes de la classe ArrayList :
Methodes :
Ajout de l'élément de valeur 1 : .add(1) ;
La taille de la liste : .size() ;
Vrai si la liste est vide : .isEmpty() ;
Accès au 11ème élément : .get(10) ; // car ça commence a 0
Remplacement du 11ème élément par la valeur 3 : .set(10,3) ;
Vrai si la liste contient la valeur 3 : .countains(3) ;
Indice de la première occurence de l'élément 3 dans la liste : .indexOf(3) ;
Suppression de l'élément en 11ème position : .remove(10) ;
suppression du premier élément de valeur 3 : .remove(new Integer(3)) ;
L'objet ArrayList
Voici un objet bien pratique. ArrayList est un de ces objets qui n'ont pas de taille
limite et qui, en plus, acceptent n'importe quel type de données, y compris null ! Nous
pouvons mettre tout ce que nous voulons dans un ArrayList. Elle est plus rapide pour
accéder à un élément.
L'objet LinkedList
Une liste chaînée (LinkedList en anglais) est une liste dont chaque élément est lié aux
éléments voisins par une référence à ces derniers. Chaque élément contient une
référence à l'élément précédent et à l'élément suivant, excepté le premier, dont
l'élément précédent vaut null, et le dernier, dont l'élément suivant vaut également
null. Plus rapide quand on ajouter au début.
Implémentation :
- Avantage : permet des ajouts et des suppressions à une position donnée en un temps
contant quelques soit la position.
- Inconvénient : l’accès à un élément (lecture) dans la liste sera peu efficace puisqu’il
nécessitera obligatoirement de parcourir une partie de la liste.
Classe Collection
On utilise aussi des methodes STATIC de la classe Collection pour manipuler nos
listes. Pour l’utiliser, un import est obligatoire :
import java.util.Collections ;
Elle offre les méthodes de classe suivantes pour une liste d’entiers :
- pour obtenir l'élément maximum de la liste : Collections.max(liste) ;
- pour trier la liste : Collections.sort(liste) ;
- pour inverser la liste : Collections.reverse(liste) ;
- pour mélanger la liste : Collections.shuffle(liste) ;
La méthode compareTo()
Attention :
Sachant que .get(0) représente le premier élément d’une liste, l’accès au nième
élément s’écrit .get(n). L’indice de la liste et varient donc entre 0 et .size() - 1. Utiliser
un indice n supérieur à .size() - 1 générera une erreur d’exécution du type :
java.lang.ArrayIndexOutOfBoundsException
2) Exemple :
import java.util.ArrayList ;
Va afficher 12 47
37. Equals
L'opérateur == vérifie que deux objets possèdent la même référence mémoire et sont
donc en fait le même objet. Il va de soi que deux objets identiques sont égaux mais,
deux objets de références mémoire différentes peuvent également être égaux. C’est
une méthode d’Object qui permet de comparer deux objets entre eux (ou, plus
précisément, elle vérifie que les deux références d'objet sont identiques si ils ont le
même contenu en fait). L'utilisation de cette méthode n'est pas aussi simple que cela,
car elle est implémentée de manière très différente au sein de plus de 150 classes
différentes sur l'ensemble de l'API Java. On peut dire tout simplement que equals()
permet de comparer deux objets, si tant est que ces objets implémentent cette
méthode.
class Point {
private int x, y ;
L'Unicode est un standard informatique qui permet des échanges de textes dans
différentes langues, à un niveau mondial. Il permet le codage de texte écrit en
donnant à tout caractère de n'importe quel système d'écriture un nom et un identifiant
numérique, et ce de manière unifiée, quelque soit la plateforme informatique ou le
logiciel.
Bien que l'Unicode ait été conçu sur le modèle du jeu de caractère ASCII, il va bien
au-delà des capacité rudimentaires d'ASCII qui ne code que les majuscules et
minuscules de A à Z et qui est codé sur 7 bits. Unicode permet de tous coder, tout les
caractères utilisés par toutes les langues écrite dans le monde cela fait + d'un million
de caractère.
Le codage de caractère Unicode traite les caractère alphabétique, les caractères
idéographiques et les symbole de manière équivalente avec comme conséquence que
tous les caractères peuvent se côtoyer dans n'importe quel ordre avec la même
facilité.
En Unicode, chaque caractère a une valeur numérique et un nom comme tous les
normes de codage qui le précèdent. Cependant, l'unicode fournit d'autres informations
afin de s'assurer que le texte soit lisible, le dévloppement de mise en œuvres
cohérentes et l'échanges de données unicode.
En d'autres termes, Unicode donne un code qui sera unique pour chaque caractère.
Mais on n'utilise différents codage comme UTF-8, UTF-16 et UTF-32 pour pouvoir
représenter ces codes sur + ou – de bits.
UTF8 est un codage de caractère informatique conçu pour coder l'ensemble des
caractères du « répertoire universel de caractère codés ». En UTF-8 le nombre de
bytes utilisés varie de 1 à 4. C'est un codage très utilisé et nous l'avons par exemple
utilisé pour pouvoir introduire les accents dans notre commande javadoc sur Linux.
Si on code sur un octet le caractère codé peut aller de 0x00 à 0x7F (en hexadécimal),
soit 128 caractères, comme en ASCII.
On pourrait également coder sur 2,3 ou 4 octets, les valeurs iront pour 2 octets de
0x0080 (soit 128) à 0x0FFF (soit 4095). Pour savoir sur combien de bit un caractère
doit être codé on s'aide de l'information donnée par les bits de poids fort pour préciser
le nombre de byte utilisé.
La représentation sera du type 1110 0000 101nnnnn 10nnnnnn (on applique une sorte
de masque sur le codage en binaire de 8365) pour € qui est codé sur 3 octets, malgré
le fait que 8365 soit possible a coder sur 2 bit la codification pour UTF-8 a besoin de
14 bits donc 3 octets.
UTF16 est un codage de caractère ou chaque caractère est codé sur une suite de un ou
2 mots de 16 bits. Le numéro de chaque caractère est repris à l'identique par le
standard Unicode ( on va de 0x0000 à 0x10FFFF). C'était dans la version originale de
l'Unicode, mais dans sa nouvelle version, c'est sur 21 bits.
UTF32 est utilisé lorsque la place mémoire n'est pas un problème et que l'on a besoin
d'avoir accès a des caractère de manière directe et sans changement de taille
Maintenant voyons voir l'utilisation d'Unicode en Java. Pour représenter les char,
Java n'autorise que les caractères qui sont compris entre U+0000 et U+FFFF ce qui
correspond a la taille du char (qui est codé sur 2 bytes, donc on utilise UTF-16)
Unicode a depuis accrus le nombre de caractère possible a coder et utilise maintenant
une plus grande palette de codes différents, on code de U+0000 à U+10FFFF.
Pour la représentation des String, Java utilise les caractère pour les représenter, il
y'aura deux manières. Lorsqu'un caractère est un caractère de base qui est codé sur 16
bits donc 2 bytes, on utilise un char. Lorsque c'est un caractère étendu, Java utilisera 2
char.
Ex : Caractère « clé de sol » qui est U+1D11E. Pour pouvoir le représenter dans un
String (on pourra pas le coder dans un char, vu que c'est un caractère étendu, il lui
faut 2 char), on doit faire une manipulation.
0000110100 0100011110
String s = ''\uD834\uDD1E'' ;
Malgré tout, ça ne veut pas dire que le caractère va s'afficher a l'écran, en effet, cela
dépends d'autres choses qui ne sont pas liés au java :)
39. Polymorphisme
Exemple :
L'ArrayList est de type tableau EtreHumain mais je peux y ajouter des objets de type
Homme et Femme ( qui sont aussi des etres humains )
Lorsque on affecte à une variable de type superclasse une variable de type sous classe
, ça ne pose pas de probleme au compilateur. On peut donc mettre des femmes dans
un tableau d'EtreHumain.
Pour vous expliquez ce que le polymorphisme , je vais créer une classe EtreHumain :
Class ettreHumain{
Comme vous avez pu remarqué j'ai reécris la methode cheveux pour les deux classes
car bon une femme sa pisse assis et un homme sa pisse debout sauf les zwet
J'ai declarer une arrayList d'EtreHumain et j'y ai rajouté des hommes et des femmes.
Ensuite j'applique la methode uriner sur tout les objets de la liste etreHumain.cheveux
Alors à votre avis , quel methode sera utiliser ? Celle de la classe etreHumain ou celle
des classes homme et femme ?
dans notre cas le type est Personnage donc la methode rencontrer qu'on va utiliser est
la methode rencontrer de Personnage,
on va considerer que c'est le type de l'objet stocker dans la variable qui va etre utiliser
pour choisir la methode à appliquer.
Dans notre exemple, on a un type personnage mais qui continent une reference à un
objet de type guerrier. On va donc choisir la methode rencontrer de guerrier.
1. Path
Un fichier est identifié par son chemin a travers le filesystem via son nom
completement qualifié (aussi nommé FQN) et son Path qui signifie chemin.
On voit déjà que le séparateur est différent en fonction de l'OS. On aura \ pour
Windows et / pour Linux. On sais qu'un path peut être relatif (a partir de l'endroit
courant) ou absolu (a partir de la racine, chemin qui fonctionnera dans tout les cas).
On utilise la classe utilitaire Paths pour créer un Path a partir de l'interface. Cette
classe appartiens au package java.nio
Exemple :
Un fichier que représente le chemin peut ne pas exister (ici, on sait tous qu'il existe
hn).
On peut donc utiliser les informations contenues dans un path via plusieurs méthodes
par exemple pour le path :
Les conversions de Paths sont multiple, on peut convertir en URI (uniform ressource
identifier), en chemin absolu, en chemin réel (comme chemin absolu, mais si c'est un
lien, alors ça donnera le path du fichier d'origine) et on pourra également résoudre un
chemin sur base de deux chemins incomplets.
Exemple :
affichera file:///C:/othman/viveLeCobol
affichera /home/hmido/projetRachat/khalidou
Pour transformer en chemin réel même résultat que pour toAbsolutePath(), si ce n'est
pas un lien, si sa en est un,il est remplacé par le chemin vers lequel il pointe
Il existe également la méthode Path.resolve qui permet créer un chemin sur base de
deux chemins différents.
Par exemple
2.Flux englobant
Dans les exemples vu pour l'écriture dans des fichiers , la lecture et l’écriture est prise
en charge par l’os mais il y a des risques de lenteurs et java propose de buffériser ses
flux (stream). C’est-à-dire qu’un flux lit dans un buffer, lorsque le buffer est vide
l’API est appelé pour une lecture qui va remplir le buffer. Ces flux rentrent dans une
catégorie de flux nommée Flux Englobant. Ils sont utilisés pour la lecture et l'écriture.
BufferedInputStream et BufferedOutputStream
BufferedWriter
BufferedWriter(Writer out)
BufferedWriter(Writer out, int taille tampon)
Dans un cas on précise la taille du tampon, dans l'autre cas non, mais pour la plupart
des utilisation, c'est bien assez.
BufferReader
Permet de doter un flux texte d'entrée d'un tampon
BufferedReader(Reader in)
BufferedReader(Reader in, int taille tampon)
Même chose pour la taille du tampon, la plupart du temps c'est bien assez.
Exemples :
Exemple DataInputStream:
Lance une EOFException si tentative de lecture au-delà de fin du fichier, pas besoin
de valeur sentinelle du genre 'on lis rien donc on s'arrête', ça s'arrêtera si on met un
catch pour attraper EOFException et le try with ressources fermera de toute façon les
flux. Il faut savoir qu'EOFException hérite de IOException, du coup les exemple au
dessus sont valable.
Maintenant voyons voir les cas ou l'on veut lire ou écrire des données primitives dans
un fichier texte. Il y'a deux manières de lire des données primitives dans les fichiers
textes.
On peut procéder par une combinaison BufferReader et conversion en passant par les
Wrapper Integer, Boolean ou Double par exemple.
Par contre, le soucis proviens quand on lis quelque chose qui n'est pas un int. Il y'aura
une InputMismatchException donc a utiliser seulement quand on est sûr de soi ou un
seul type de donnée primitive dans le fichier, dans l'autre cas il existe la lecture via la
classe Scanner.
En effet, comme on l'a toujours fait, on a lus des entiers au clavier, mais on peut aussi
lire depuis un fichier sans soucis, le constructeur de Scanner le permet (voir
Scanner/Console).
Exemple :
Pour écrire dans les fichiers texte des données primitives, on utilise printWriter qui
est également un flux englobant
PrintWriter
Flux texte de sortie(out), propose les méthodes println, print et printf (pour formater
comme String.format() ;
PrintWriter(OutputStream fluxSortie)
PrintWriter(Writer fluxTexteSortie)
void print(String texte)
void println(String texte)
Exemple :
Les deux sujets sont très liés, si vous parlez de l'un vous devrez parler de l'autre c'est
obligatoire, surtout pour l'écriture dans les fichiers qui reviens pour les primitifs ainsi
que le concept de Path qui reviens tout le temps quoiqu'il arrive.