5. Les objets en Java
Java est un langage orienté objet presque pur. Un programme en
Java se constitue d'un ensemble des objets qui communiquent entre eux.
Les classes représentent des modèles des objets. Elles
définissent leur type – les membres données et les
méthodes qui déterminent le comportement de l'objet.
Chaque objet est une réalisation concrète de la
modèle définit par la classe correspondant. Il correspond
à la notion de variable de type définit par la classe. On
dit que les objets sont instances des classes.
5.1
Définition d'une classe
Le canevas général de définition d’une
classe en Java est le suivant:
public class nom
{ // définition des variables membres(variables d'instances) et
des méthodes de la classe
}
Exemple:
public class Person {
public String name = "namePers";
public int age;
public Person(){
name = "name1";
age = 21;
}
public void growUp(int years) {
age += years;
}
}
La définition d'un variable d'instance contient:
• le mode d’accès qui
définit la visibilité de la variable en dehors de la
classe; la visibilité sera discuté en détails un
peu plus tard;
• le type de la variable;
• le nom de la variable.
Ces déclarations peuvent être placées où
vous voulez à l’intérieur de la définition
de la classe, et pas nécessairement avant les méthodes
.
La définition d’une méthode ressemble à
celle d’une fonction dans les autres langages. Elle se compose
d’un en-tête et d’un bloc.
L’en-tête précise :
• le nom de la méthode – dans
l'exemple growUp;
• le mode d’accès - dans l'exemple
public, visible partout;
• les arguments qui seront fournis à la
méthode lors de son appel (int years);
• le type de la valeur de retour – void,
(sans une valeur de retour).
Dans la méthode growUp
la variable years
désigne la valeur reçue en premier argument. La variable age désigne le champ age
de l’objet de type Person qui sera effectivement concerné
par l’appel de growUp.
5.2
Instance d'une classe
public class Test {
public static void main (String[] arg){
Person p1;
p1 = new Person();
Person p2 = new Person();
p2.growUp(4);
System.out.println("p1.age:
"+p1.age);
System.out.println("p2.age:
"+p2.age);
}
}
La classe Test possède une méthode main() qui le
transforme dans une application qui pourrait être lancée
On va mettre la classe Test dans le même répertoire que la
classe Person. Si on lance la classe Test résultat obtenu et :
p1.age: 21
p2.age: 25
La déclaration Person p1; est différente de la
déclaration d’une variable d’un type primitif (comme
int n;). Elle ne réserve pas d’emplacement pour un objet
de type Person, mais seulement un emplacement pour une
référence à un objet de type Person. Avant de la
création de l'objet cette référence est
initialisée à une valeur spéciale – null.
Cette valeur indique que la référence n'est pas encore
liée à un objet. Si on fait une essaie de l'utiliser on
obtient une erreur lors d'exécution.
Person p1;
System.out.println("p1.age:
"+p1.age);
//erreur Null pointer access
L’emplacement pour l’objet sera alloué sur une
demande explicite du programme, en faisant appel à un
opérateur nommé new
qui utilise le constructeur Person ()
pour donner les valeurs initiales aux variables d'instances. Ainsi,
l’expression:
p1 = new Person();
crée un emplacement pour un objet de type Person et fournit sa
référence en l'affectant à p1.
constructeur Person() fait l'initialisation des deux variables membres
de l'objet – name et age:
name = "name1";
age = 21;
Fig. 5.1.
Référence et l'objet
5.3
Constructeurs
Un constructeur c'est une méthode spéciale, sans valeur
de retour, portant le même nom que la classe. Il peut disposer
d’un nombre quelconque d’arguments (éventuellement
aucun). Il est utilisé avec le mot clé new pendant la création d'un
objet pour donner la valeur initiale des variables membres de
l'instance créée.
Person p2 = new Person();
C'est la seule méthode en Java qui ne déclare pas le type
de résultat de la méthode. Même la présence
de void est une erreur.
Remarques:
• Une classe peut ne disposer d’aucun
constructeur. Dans ce cas c'est la machine virtuelle Java qui fournit
un constructeur par défault qui ne fait rien. Dès
qu’une classe possède au moins un constructeur (elle peut
en comporter plusieurs), ce pseudo-constructeur par défaut ne
peut plus être utilisé.
• Pour pouvoir être appelé de
l'extérieur le constructeur dois être
déclaré public. s'il est déclaré private,
la seule possibilité c'est d'être appelé par un
autre constructeur.
5.4
Construction et initialisation d’un objet
Contrairement à ce qui se passe pour les variables locales, les
variables membres d’un objet sont toujours initialisés par
défaut.
La création d’un objet entraîne toujours, par ordre
chronologique, les opérations suivante:
• une initialisation par défaut de tous
les champs de l’objet,
• une initialisation explicite lors de la
déclaration du champ,
• l’exécution des instructions du
corps du constructeur
5.4.1
Initialisation par défaut des champs d’un objet
Type de la variable
|
Valeur par défaut
|
boolean
|
false
|
char
|
'\u0000'
|
entier (byte, short, int, long)
|
0
|
float
|
0.f
|
double
|
0.
|
objet
|
null
|
Tab. 5.1
Initialisation par défaut des variables d’un objet
5.4.2
Initialisation explicite des champs d’un objet
public String name = "namePers";
5.4.3 Appel du
constructeur
Leconstructeur n’est exécuté qu’après
l’initialisation par défaut et l’initialisation
explicite.
Les possibilités
offertes par le constructeur sont beaucoup plus larges que les
initialisations
explicites. Sauf cas particulier, il est donc préférable
d’effectuer les
initialisations dans le constructeur.
5.4.4 Variables
membres déclarés avec l’attribut final
public class Ex1 {
private final int m = 10;
public static void main(String arg[]){
Ex1 e1,e2;
e1=new Ex1();
e2=new Ex1();
System.out.println("e1.m =
"+e1.m+" e2.m = "+e2.m);
}
}
e1.m = 10 e2.m = 10
public class Ex2 {
public Ex2(int arg) {
m = arg ;
}
private final int m ;
public static void main(String arg[]){
Ex2 e1,e2;
e1=new Ex2(3);
e2=new Ex2(10);
System.out.println("e1.m=
"+e1.m+" e2.m= "+e2.m);
}
}
e1.m=3 e2.m=10
5.5
L'accès aux membres
Aucune restriction à l'intérieur d'une classe.
À l'extérieur - modificateurs de visibilité :
public, private, protected, sans.
private String name = "namePers";
private int age;
public class Test {
public static void main (String[] arg){
…
System.out.println("p1.age:
"+p1.age); //erreur de compilation
System.out.println("p2.age:
"+p2.age); //erreur de compilation
}
}
Les problèmes de la visibilité seront
discutés plus en détails dans la section de packages de
ce
cours.
5.6 Membres
statiques
Les variables membres et les méthodes ne sont accessibles
qu'à travers l'objet particulier auquel elles sont
associées. Par contre, si les membres sont
déclarés avec le modificateur static, ils sont
partagés par toutes les instances da la classe. Les variables
déclarées avec ce modificateur sont appelées des
variables statiques ou variables de classe. De même les
méthodes qui sont déclarées avec le modificateur
static sont appelées des méthodes statiques ou
méthodes de classe.
public class Person {
static int num=0;
public String name;
private int age,nm;
public Person(){
nm = ++num;
name = "name"+nm;
age = 20+nm;
}
public void growUp(int years) {
age += years;
}
public void prt(){
System.out.println ("name:
"+name+" age :"+age+" number:"+nm);
}
}
-----------------------------------------------------
public class Test {
public static void main (String[] arg){
Person p1;
p1 = new Person();
p1.prt();
Person p2 = new Person();
p2.prt();
p2.growUp(4);
System.out.println("\t\tAfter grow up");
p2.prt();
}
}
Fig. 5.2 Membre
statique - num
5.7
Ramasse-miettes
Il n’existe aucun opérateur permettant
de détruire un objet dont on n’aurait plus besoin. La
démarche employée par Java est un mécanisme de
gestion automatique de la mémoire connu sous le nom de
ramasse-miettes (en anglais Garbage Collector).
Lorsqu’il n’existe plus aucune référence sur
un objet, on est certain que le programme ne pourra plus y
accéder et l'objet est devenu candidat pour être
ramassé. Le ramasse-miettes se déclenche
automatiquement quand on commence d'avoir des problèmes
pour trouver assez de mémoire libre. Avant qu’un objet
soit soumis au ramasse-miettes, la machine virtuelle Java essaie
d'appeler la méthode finalize() de sa classe (si elle existe
bien sûr).
L'exemple suivant montre comment fonctionne le ramasse-miette. La
classe Garbage créée dans une boucle des objets de la
classe Test et attend le démarrage du ramasse-miette. La classe
Test contient quatre variables statiques:
stopNew – la valeur true
arrête la création des objets de la classe Test;
startGarbage – la valeur
true montre que le ramasse-miette a commence de travailler;
created – compte le
nombre des objets de la classe Test déjà
créés;
finalized – compte le
nombre des objets de la classe Test déjà ramassés.
La première fois quand la méthode finalize() est
appelée par le ramasse-miettes la création des objets est
arrêté. A la fin, le programme affiche combien d'objets
sont créés, quand a démarré le
ramasse-miettes et combien d'objets sont ramassés
class Test {
static boolean stopNew = false;
static int created = 0;
static int finalized = 0;
static boolean startGarbage=
false;
int num;
Test() {
num = ++created;
new String("To take up space");
}
protected void finalize() {
if(!startGarbage){
System.out.println("Beginning to finalize after " + created
+ " Tests have been created");
startGarbage =
true;
stopNew = true;
}
finalized++;
if(finalized >= created)
System.out.println("All " + finalized + " finalized");
}
}
//------------------------
public class Garbage {
public static void main(String[] args) {
while(!Test.stopNew) {
new
Test();
}
System.out.println("After all
Tests have been created:\n" +
"total created = " + Test.created +
", total finalized = " + Test.finalized);
System.out.println("bye!");
}
}
5.8
Méthodes
5.8.1 Variables
locales
Allouées et initialisées explicitement quand la
méthode est appelée et détruites lorsque la
méthode se termine.
Les variables locales doivent être initialisées
explicitement avant d'être utilisées!
void f(){
...
int var;
if(condition){
var= 10;
}
var++;
//erreur initialisation
...
}
5.8.2 Passage
d'arguments
• par valeur : la méthode reçoit
une copie de la valeur de l’argument effectif ; elle travaille
sur cette copie qu’elle peut modifier à sa guise, sans que
cela n’ait d’incidence sur la valeur de l’argument
effectif - types primitifs;
• par adresse (ou par référence) :
la méthode reçoit l’adresse (ou la
référence) de l’argument effectif avec lequel elle
travaille alors directement ; elle peut donc, le cas
échéant, en modifier la valeur - objets.
class Obj {
int i;
Obj(){
i=5;
}
}
public class Test{
public static void main(String arg[]){
int m=4;
Obj pr = new Obj();
System.out.println("before:
m="+m+"\t pr.i="+pr.i);
f(m,pr);
System.out.println("after:
m="+m+"\t pr.i="+pr.i);
}
static void f(int k, Obj p){
k++;
p.i++;
}
}
5.8.3 La
référence this
Parametre invisible implicite.
Revenons à la
déclaration de la méthode growUp:
public void growUp(int years) {
age += years;
}
Pour utiliser la méthode on
fait un appel avec la
référence d'un objet de type Person:
p2.growUp(4);
Dans la déclaration
de la méthode figure
un seul paramètre mais en réalité elle a deux
paramètres. Le deuxième est un
paramètre explicite qui est visible dans la déclaration
– years. Le premier, appelé
paramètre implicite est invisible. Il
représente l'objet à partir du quel la
méthode a été appelée (dans notre cas
– p2).
Cet objet peut être référencé dans le corps
de la méthode par le mot clé this.
L'identificateur spécial this
correspond à l'objet qui est en train d'être
manipulé. Il est souvent appelé la
"référence this".
La méthode growUp
pourrait être écrite de la façon suivante:
public void growUp(int years) {
this.age
+= years;
}
Si une variable locale et une variable d'instance ont le même
nom, la variable locale masque le nom de la variable d'instance - this
devient obligatoire.
public class Person {
String name = "namePers";
int age;
public Person(){
name = "name1";
age = 21;
}
public void growUp(int age) {
this.age += age;
}
}
5.8.4
Méthodes statiques
Les méthodes statiques (on les appelle souvent
méthodes de classe) jouent un rôle indépendant d’un
quelconque objet.
L’appel d’une telle méthode ne nécessite plus
que le nom de la classe
correspondante. Vous pouvez toujours appeler une telle méthode
en la faisant lier
artificiellement sur un objet de la classe (alors que la
référence à un tel objet
n’est pas utile).
class Stat { .....
private double x;
// variable
usuelle
private static int n;
// variable de
classe
.....
public void fu() {
//
méthode usuelle
fs()
;
// appel direct d'une méthode statique
n = …
//
accès direct au variable de classe
x = …
//
accès direct au variable usuelle
…
}
public static void fs() {
// méthode de classe
.....
// on ne peut
pas accéder directement à x, et à fu(). Il faut
l'accéder via une référence à
objet.
n = …
// on peut accéder aux
variables et aux méthodes de classe
}
public static void main(String[] arg)
{ // méthode de classe
Stat objStat;
…
fs();
// appel
directe d'une méthode statique
objStat.fs();
// reste autorisé, mais
déconseillé
objStat.x =
…
// accès au variable usuelle par un objet
objStat.fu();
// accès au méthode usuelle par un
objet
}
Les méthodes statiques ne
reçoivent pas le paramètre implicite this
5.9
Affectation et comparaison d’objets
5.9.1
Affectation d’objets
Les
affectations entre les objets portent sur les références
et non sur les objets
eux-mêmes
class Ex{
int x;
int y;
Ex(int x, int y){
this.x=x;
this.y = y;
}
}
public class Affect {
public static void main(String arg[]){
Ex a, b;
a= new Ex(3,5);
b= new Ex (2,0);
System.out.print("before
assign: ");
System.out.print ("\t a =
("+a.x+","+a.y+")");
System.out.println ("\t b =
("+b.x+","+b.y+")");
//assign
a = b;
System.out.print("after
assign: ");
System.out.print ("\t a =
("+a.x+","+a.y+")");
System.out.println ("\t b =
("+b.x+","+b.y+")");
//modification of a,
modify also b :
a.x++;
System.out.print("after
modification on a ");
System.out.print ("\t a =
("+a.x+","+a.y+")");
System.out.println ("\t b =
("+b.x+","+b.y+")");
}
}
Fig. 5.3. Les deux objets avant l'affectation
Fig. 5.4. Les deux objets après l'affectation
5.9.2
Comparaison d’objets
Les opérateurs == et != s’appliquent à des objets.
Ils portent sur les références.
L’expression a == b est vraie uniquement si a et b font
référence à un seul et même objet, et non
pas si les valeurs des champs de a et b sont les mêmes.
Pour verifier si les valeurs des champs son les mêmes, il faut
créer une méthode propre .
Toutes les classes héritent une méthode de la classe de
base Objet:
public boolean equals(Object obj)
obj
- the reference object with which to compare.
Pour les classes systèmes (par exemple String) la méthode
est redéfinie correctement, mais pour les classes
créées par utilisateur elle doit être
redéfinie (sinon il compare les références).
5.9.3 La notion
de clone
On a besoin d'une méthode spéciale pour effectuer la
recopie de tous les champs d’un objet dans un autre objet de
même type. Toutefois, si les données sont convenablement
encapsulées, il n’est pas possible d’y
accéder directement. On doit s’appuyer sur
l’existence de méthodes d’accès et
d’altération de ces variables membres privés. La
recopie complète d’un objet nécessiterait une bonne
connaissance de son implémentation.
Dans certaines situations la
copie devient une procédure récursive. La démarche la plus rationnelle pour traiter
cette copie qu’on nomme clonage en Java, consiste à faire
en sorte que chaque
classe concernée
par l’éventuelle récursivité dispose de sa
propre méthode
5.10
Surcharge de méthodes
5.10.1
Définition
Surcharge (en anglais overloading) - plusieurs méthodes d'une
classe peuvent porter le même nom, à condition que le
nombre et le type de leurs arguments permettent au compilateur
d’effectuer son choix.
5.10.2 Exemple
public class Person {
String name;
int age;
Person(){
name = "name 1";
age = 20;
}
Person(String name){
this.name=name;
age=20;
}
Person(int age){
name="name 2";
this.age=age;
}
Person(String name, int age){
this.name=name;
this.age=age;
}
public static void main(String[] arg){
Person ps[]=new Person[4];
ps[0]= new Person();
ps[1]= new Person(22);
ps[2]= new Person("name 3");
ps[3]= new Person("name
4",26);
main(ps);
}
public static void main(Person[] ps){
for(int
i=0;i<ps.length;i++){
System.out.print(ps[i].name);
System.out.println(" age: "+ps[i].age);
}
}
}
5.10.3
Règles générales
Le compilateur recherche toutes les méthodes acceptables et il
choisit la meilleure si elle existe. Pour qu’une méthode
soit acceptable, il faut:
• qu’elle dispose du nombre
d’arguments voulus;
• que le type de chaque argument effectif soit
compatible par affectation avec le type de l’argument muet
correspondant,
• qu’elle soit accessible;
Le choix de la méthode se déroule suivant les
règles:
• Si aucune méthode n’est
acceptable, il y a erreur de compilation.
• Si une seule méthode est acceptable,
elle est utilisée pour l’appel.
• Si plusieurs méthodes sont acceptables,
le compilateur essaie d’en trouver une qui soit meilleure que
toutes les autres. Pour ce faire, il procède par
éliminations successives.
Après élimination de toutes les méthodes possibles
:
• s’il ne reste plus qu’une seule
méthode, elle est utilisée,
• s’il n’en reste aucune, on obtient
une erreur de compilation,
• s’il en reste plusieurs, on obtient une
erreur de compilation mentionnant une ambiguïté.
5.11 Les
packages
Un regroupement logique sous un identificateur commun d’un
ensemble de tous les classes dans une répertoire. Proche de la
notion de bibliothèque. Il permet de répartir
les classes correspondantes dans différents packages. Le risque
de créer deux classes de même nom se trouve alors
limité aux seules classes d’un même package.
5.11.1
Utilisation
Une classe peut utiliser toutes les classes de son propre package et
toutes les classes publiques des autres packages
par le nom complet :
java.util.Date today = new
java.util.Date();
java.sql.Date deadline = new
java.sql.Date(1567890056871L);
ou par importer la classe spécifique :
import java.util.Date;
…
Date today = new Date();
Il est plus simple d'importer toutes les classes du package
import java.util.*;
…
Date today = new Date();
Attention pour un conflit de nom possible:
import java.util.*
import java.sql.*
…
Date today;
// erreur
5.11.2 Ajout
d'une classe dans un package
Il faut mettre le nom du package en haut du fichier source da la
classe, avant tous autre code. S'il n'y a pas une instruction package
dans le fichier source, les classes dans ce fichier source
appartiendront au package par défaut qui n'a pas de nom.
Jusqu'à présent tous les exemples de classes se
trouvaient dans le package par défaut.
Comme exemple nous allons prendre le programme du 5.10.2 mais un peu
modifié et réparti en deux packages: test.first et pers.
Les fichiers doivent être mis dans le système de fichier
selon le schéma suivant:
Fig.5.5 Schéma des fichiers pour les packages test.first et pers
package test.first;
import pers.*;
public class Test {
public static void main(String[] arg){
Person ps[]=new Person[4];
ps[0]= new Person();
ps[1]= new Person(22);
ps[2]= new Person("name 3");
ps[3]= new Person("name 4",26);
prt(ps);
}
public static void prt(Person[] ps){
for(int i=0;i<ps.length;i++){
System.out.print(ps[i].getName());
System.out.println(" age: "+ps[i].getAge());
}
}
}
package pers;
public class Person {
private String name;
private int age;
public Person(){
name = "name 1";
age = 20;
}
public Person(String name){
this.name=name;
age=20;
}
public Person(int age){
name="name 2";
this.age=age;
}
public Person(String name, int age){
this.name=name;
this.age=age;
}
public String getName(){
return this.name;
}
public int getAge(){
return this.age;
}
}
En dehors d'environnement Eclipse le
lancement du programme se fait à partir du répertoire
courant!
java test.first.Test
Deux modifiers de la
visibilité au niveau de classe: public; et par défaut (sans modifier)
public class Name1{ //visible partout
...
}
class Name2 { //ne visible
que dans le package (le répertoire)
...
}
5.11.3 La
visibilité des membres d'une classe
Modifier
|
class
|
package
|
subclass
|
world
|
public
|
X
|
X
|
X
|
X
|
protected
|
X
|
X
|
X
|
|
no modifier
|
X
|
X
|
|
|
private
|
X
|
|
|
|
Tab 5.2 La visibilité des membres d'une classe
package one;
public class Alpha {
String name;
public String fNumber;
protected int age;
private String friend;
public Alpha(){
}
public Alpha(String name,String fn,
int age,String friend){
this.name=name;
fNumber=fn;
this.age=age;
this.friend=friend;
}
public String getFriend(){
return friend;
}
}
package one;
public class Beta {
public static void main(String [] arg){
Alpha alpha = new Alpha("Pijo",
"1234",19,"Penda");
System.out.println (alpha.name);
System.out.println
(alpha.fNumber);
System.out.println (alpha.age);
//System.out.println
(alpha.friend);
error
System.out.println
(alpha.getFriend());
}
}
package two;
public class AlphaSub extends one.Alpha{
AlphaSub(String name,String fn,int age,String
friend){
super(name,fn,age,friend);
}
public static void main(String [] arg){
AlphaSub alpha = new
AlphaSub("Pijo","1234",19,"Penda");
//System.out.println
(alpha.name);
error
System.out.println
(alpha.fNumber);
System.out.println
(alpha.age);
// accessible
//System.out.println
(alpha.friend);
error
System.out.println
(alpha.getFriend());
}
}
package two;
import one.*;
public class Gama {
public static void main(String [] arg){
Alpha alpha = new
Alpha("Pijo","1234",19,"Penda");
//System.out.println
(alpha.name);
error
System.out.println
(alpha.fNumber);
//System.out.println
(alpha.age);
error
//System.out.println
(alpha.friend);
error
System.out.println
(alpha.getFriend());
}
}
5.12 Les
classes enveloppes
type primitif
|
classe enveloppe
|
boolean
|
Boolean
|
char
|
Character
|
byte
|
Byte
|
short
|
Short
|
int
|
Integer
|
long
|
Long
|
float
|
Float
|
double
|
Double
|
void
|
Void
|
–
|
BigInteger
|
–
|
BigDecimal
|
Tab.
5.3 Classes enveloppes
Toutes les classes enveloppes disposent d’un constructeur
recevant un argument d’un type primitif :
Character cObj = new Character('d');
Boolean bObj = new Boolean(true);
Float fObj = new Float(4.3f);
int m=4, n=7;
double d = 15.4;
Double dObj = new Double(fp);
Integer iObj = new Integer(m+n);
Méthode de la forme xxxValue
(xxx représentant le nom du
type primitif) qui permet de retrouver la valeur du type primitif
correspondant :
char c = cObj.charValue;
float f = fObj.floatFalue;
emballage (boxing) et
débalage (unboxing)
Le compilateur Java effectue une conversion automatique dans les
expressions entre les variables primitives et leurs wrappers d'objets
correspondants. Conversion de la variable primitive vers wrapper objet
s'appelle boxing, dans l'autre sens - unboxing.
Character cObj = 'd'; //boxing
Boolean bObj = true;
float fp = 15.4;
Double dObj = fp+7.3;
char c =cObj; // unboxing
double k = dOj+7.5;
Ces classes enveloppes sont immutables : elles ne changeront pas de
valeur, à chaque fois que l'on modifie un objet, Java
recrée un autre objet avec la nouvelle valeur.
Trois raisons pour utiliser une classe enveloppe à la place de
type primitif:
• Pour le stockage dans les listes qui ne se
fait que pour des objets.
• Pour utiliser un constant définit dans
la classe. Par exemple MIN_VALUE ou bien MAX_VALUE.
• Pour utiliser les méthodes pour
conversion des types, conversion à partir de strings, et pour
conversion entre les systèmes (décimal, octal,
hexadécimal, binaire).
public class WrapClass {
public static void main(String args[]) {
Boolean b1 = true;
Boolean b2 = new Boolean("FALSE");
System.out.print ("The digits in
hexadecimal: ");
for(int j=0;j<16;++j)
System.out.print(Character.forDigit(j,16)+" ");
System.out.println();
int m = Integer.parseInt("254");
int i = Integer.parseInt("ef",16);
long ln =
Long.parseLong("abcd",16);
System.out.println(ln + " radix =
10: "+ln);
System.out.println(ln+" radix=2:
"+Long.toString(ln,2));
System.out.println(ln+" radix=16:
"+Long.toString(ln,16));
System.out.println("float min
value: "+Float.MIN_VALUE);
System.out.println("double max
value: "+Double.MAX_VALUE);
System.out.println("valeurs
boolean: "+ b1+ "\t"+b2);
}
}
Les objets de deux classes BigInteger et BigDecimal sont internement
représentés comme chaines de caractères. Ils
n'ont pas de limite des digits, mais pour les opérations
arithmétiques il faut utiliser des méthodes à la
place des opérateurs:
import java.math.BigInteger;
public class Test {
public static void main(String ar[]) {
BigInteger bi=new
BigInteger("189567432185329932"),
bi2=new BigInteger("5"); //Initialization
System.out.println(bi.add(bi2));
System.out.println(bi.multiply(bi));
}
}
Dans l'exemple suivant on cherche de trouver le premier nombre premier
(entier naturel qui admet exactement deux diviseurs distincts entiers
et positifs: 1 et lui-même) qui est plus grand d'une certaine
valeur. Pour le calcul on utilise la classe enveloppe BigInteger et la
méthode isProbablePrime(). La vérification exacte, si un
grand nombre est premier ou non, prend trop de temps. La méthode
utilisée est plus rapide mais la réponse n'est pas 100%
sur. Dans l'exemple l'argument de cette méthode est choisi pour
que la possibilité que le nombre soit premier est
évalué à 99.21875%.
import java.math.BigInteger;
public class Big {
public static void main(String arg[]){
BigInteger n=new
BigInteger("1000000000000");
BigInteger one=new
BigInteger("1");
while(!n.isProbablePrime(7))
n=n.add(one);
System.out.println("\n"+n.toString(10)+" is probably prime.");
System.out.println("It is
"+n.bitLength()+" bits in length.");}
}
5.13 La
classe Math
public class MathApp {
public static void main(String args[]) {
System.out.println(Math.E);
System.out.println(Math.PI);
System.out.println(Math.abs(-1234));
System.out.println(Math.cos(Math.PI/4));
System.out.println(Math.sin(Math.PI/2));
System.out.println(Math.tan(Math.PI/4));
System.out.println(Math.log(1));
System.out.println(Math.pow(3.1,2.2)); //puissance
for(int i=0;i<3;++i)
System.out.print(Math.random()+" "); // double dans [0, 1.0)
System.out.println();
for(int i=0;i<3;++i)
System.out.print((int)(Math.random()*10)+5+" "); //entier dans
[5, 15)
System.out.println();
}
}
5.14
Entrées/sorties sur terminal
La classe System regroupe les accès aux ressources
système, fournissant des références sur la console
standard via trois variables statiques – in, out et err.
variable
|
type
|
utilisée pour
|
in
|
InputStream
|
Lecture de l'entrée standard (la console)
|
out
|
PrintStream
|
Affichage sur la sortie standard (la console)
|
err
|
PrintStream
|
Affichage sur la sortie d'erreurs standard (la console)
|
Tab. 5.4 Variables statiques
de la classe System
L’affichage dans la fenêtre console se fait par l’une
des fonctions System.out.println() ou System.out.print(). L'affichage
des erreurs se fait par les mêmes fonctions mais en utilisant la
variable statique err – System.err.println() et
System.err.println().
Pour l'entrée à partir de la console on va utiliser la
classe Scanner. La classe Scanner se trouve dans le package java.util
et il
possède des méthodes simples de lecture des variable de
types primitifs de l'entrés standard (System.in)
type de résultat
|
méthode
|
Description
|
Scanner
|
new Scanner(System.in)
|
constructeur
|
BigDecimal
|
nextBigDecimal()
|
introduit l'unité suivant de type BigDecimal
|
BigInteger
|
nextBigInteger()
|
introduit l'unité suivant de type BigInteger
|
BigInteger
|
nextBigInteger(int radix)
|
introduit l'unité suivant de type BigInteger
en utilisant un système de calcul de la base radix
|
boolean
|
nextBoolean()
|
introduit l'unité suivant de type boolean
|
byte
|
nextByte()
|
introduit l'unité suivant de type byte
|
byte
|
nextByte(int radix)
|
introduit l'unité suivant de type byte
en utilisant un système de calcul de la base radix
|
double
|
nextDouble()
|
introduit l'unité suivant de type double
|
float
|
nextFloat()
|
introduit l'unité suivant de type float
|
int
|
nextInt()
|
introduit l'unité suivant de type int
|
int
|
nextInt(int radix)
|
introduit l'unité suivant de type int
en utilisant un système de calcul de la base radix
|
String
|
nextLine()
|
introduit l'unité suivant de type String
|
long
|
nextLong
|
introduit l'unité suivant de type long
|
long
|
nextLong(int radix)
|
introduit l'unité suivant de type long
en utilisant un système de calcul de la base radix
|
short
|
nextShort()
|
introduit l'unité suivant de type short
|
short
|
nextShort(int radix)
|
introduit l'unité suivant de type short
en utilisant un système de calcul de la base radix
|
Tab. 5.5
Méthodes utiles de la classe Scanner
import java.util.*;
public class Test{
public static void main(String[]
args) {
Scanner in = new
Scanner(System.in);
System.out.print("What is your
name? ");
String name =
in.nextLine();
// get first
input
System.out.print("How old are
you? ");
int age =
in.nextInt();
// get second input
System.out.println("Hello, " +
name + ". Next year, you'll be " + (age + 1)); // display on console
}
}
Problème avec "end line"
import java.util.*;
public class Test{
public static void main(String[]
args) {
Scanner in = new
Scanner(System.in);
System.out.print("How old are
you? ");
int age =
in.nextInt();
// get second input
in.nextLine();
//for the
character "end line"
System.out.print("What is your
name? ");
String name =
in.nextLine();
// get first
input
System.out.println("Hello, " +
name + ". Next year, you'll be " + (age + 1)); // display on console
}
}
Exemple de classe BigInteger:
import java.math.BigInteger;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner in = new
Scanner(System.in);
BigInteger bi,bi2=new
BigInteger("5"); //initialize bi2
System.out.print("introduse a
BigInteger\n");
bi =
in.nextBigInteger(); // read
from keyboard
System.out.println(bi.add(bi2));
System.out.println(bi.multiply(bi));
}
}