String
prend un S majuscule
main
==true
"
{}
for
for
et while
public
"?
Quand mettre "static
"?
.class
et .java
|
et ||
,
&
et &&
.length
et .length()
String
String
prend un S majusculeMaBelleClasse
,
une méthode maBelleMethode
et une variable
ma_belle_variable
.
Ceci n'est pas obligatoire:
c'est une convention adoptée par Java.
Cela permet, par exemple, de se souvenir que la classe
String
prend une majuscule, mais pas la méthode
main
.
main
main
d'une application Java a pour
argument un objet de type String []
.
Lorsque l'on définit une classe MonBeauProgramme
dans
un fichier MonBeauProgramme.java
, on commence par compiler
par
javac MonBeauProgramme.javaet l'on peut le lancer par
java MonBeauProgramme 105 2 abc TagadaTsouinTsouin "f(x) = y" bofA ce moment, le "shell" d'Unix découpe cette ligne en plusieurs chaînes de caractères suivant la position des espaces (et des guillemets) et les range dans un tableau que l'on appelle souvent
argv
.
Dans cet exemple, on a le tableau suivant
argv[0]="java" argv[1]="MonBeauProgramme" argv[2]="105" argv[3]="2" argv[4]="abc" argv[5]="TagadaTsouinTsouin" argv[6]="f(x) = y" argv[7]="bof"Ensuite, le shell appelle le programme
java
et lui transmet
le tableau argv
.
Le programme java
comprend qu'il faut aller chercher la
méthode main
de la classe MonBeauProgramme
.
Il décale le tableau argv
de deux crans et le transmet
à main
en argument.
Ensuite, c'est le programme de la méthode main
qui se
débrouille avec le tableau de String
suivant.
argv[0]="105" argv[1]="2" argv[2]="abc" argv[3]="TagadaTsouinTsouin" argv[4]="f(x) = y" argv[5]="bof"
public void maBelleMethode(int n) { instruction1; instruction2; instruction3; }Si le bloc suit une structure
if
:
if(i<n) { instruction1; instruction2; instruction3; }Idem si le bloc est le corps d'une structure
for
.
n=10
" est une instruction qui affecte la valeur
10
à la variable n
.
En revanche, "n==10
" est une expression booléenne
qui vaut true
si la variable n
est égale
à 10
, et false
dans les autres cas.
Une erreur classique consiste à écrire
if(n=10)
qui est incorrect.
(L'erreur est notifiée par le compilateur.)
La fonction if
attend un argument de type booléen.
Il faut donc écrire if(n==10)
si l'on veut tester que
n
est égal à 10
ou non.
==true
"test
est une variable de type
boolean
, l'expresion test==true
montre que
l'on n'a pas compris la notion de booléen et risque de diminuer
l'appréciation d'un correcteur de pâle!
En effet, l'opérateur ==
donne lui-même le
type boolean
à l'expression.
Si donc test
vaut true
, l'expression retournera
la valeur true
.
Si, en revanche, test
vaut false
, l'expression
retournera la valeur false
.
En fait, test==(test==true)
est une tautologie.
Pourquoi donc utiliser une expression test==true
quand on
peut utiliser directement la valeur de test
?
On ecrira donc if(test)
et non if(test==true)
.
{}
if
ou for
acceptent une seule
instruction.
Leur syntaxe est
if(condition) instruction for(inst1;condition;inst2) instructionDans ce cas, soit on n'utilise effectivement qu'une seule instruction (donc sans
{}
) terminée par un point virgule ;
,
soit on utilise un bloc d'instructions qui commence par {
et
finit par }
.
Lorsqu'il n'y a qu'une instruction dans le bloc, on peut donc se passer des
{}
.
Cette règle s'applique également aux autres structures.
for
for
s'écrit
for(inst_init ; expr_test ; inst_trans) inst_boucleoù
inst_init
, inst_trans
et
inst_boucle
sont des instructions, et
expr_test
est une expression booléenne.
Les délimiteurs sont ici des points-virgule ";" (et non des virgules).
En général, inst_boucle
est un
bloc d'instructions délimité par "{" et "}".
Les instructions inst_init
et inst_trans
peuvent
être composées de plusieurs instructions séparées
par des virgules.
Exemple:
for(i=0 , on_y_va=true ; (i<n) && on_y_va ; i++) { inst1; inst2; if(condition) on_y_va=false; inst3; }(Noter l'emploi d'une variable booléenne
on_y_va
qui
permet de sortir de la boucle proprement.)
L'instruction inst_init
est effectuée avant la
boucle, le test expr_test
est effectué avant toute
itération (il est donc possible d'en avoir aucune), et l'instruction
inst_trans
est systématiquement effectuée
après toute itération.
for
et while
while
est
while(condition) instructionOn peut faire la même chose qu'une boucle
for
avec un
while
.
Cependant, une boucle du genre
i=0; while(i<n) { inst1; inst2; i++; }est moins lisible que
for( i=0 ; i<n ; i++ ) { inst1; inst2; }car tous les éléments importants de la boucles (initialisation, test et incrément) sont situés à des endroits différents dans la structure
while
.
On réservera donc la structure while
aux boucles qui
ne sont pas itératives et dont le comportement n'est pas
prévisible comme
while( lecon_pas_comprise ) { exo=exercice_aleatoire(); faire_exercice(exo); }
La structure while
suivante peut être plus utile.
do instruction while(condition)En effet, dans cette structure, la condition est testée à la fin de la boucle (et non au début), si bien qu'il y a toujours au moins une itération d'effectuée. Par exemple, on peut écrire
java.math.BigInteger p; // type grand entier do p=new java.math.BigInteger(300,new Random()); // entier aleatoire < 2^300 while( !p.isProbablePrime(20) ); // teste si p n'est pas premier System.out.println(p.toString()); // affiche pAvec l'autre type de boucle, il aurait fallu écrire
java.math.BigInteger p; p=new java.math.BigInteger(300,new Random()); while( !p.isProbablePrime(20) ) p=new java.math.BigInteger(300,new Random()); System.out.println(p.toString()); // affiche pet donc écrire deux fois
p=new java.math.BigInteger(300,new Random());
public
"?
Quand mettre "static
"?MaBelleClasse.java
, on définit une
et une seule classe avec public
: la classe
MaBelleClasse
;
MaBelleClasse
du fichier
MaBelleClasse.java
, on définit une méthode
main
avec public static
;
main
,
public
est inutile;
static
pour toutes les méthodes et variables globales
d'une même classe;
static
.
Pour les curieux, on met, de manière générale,
public
pour rendre la classe/méthode/variable
accessible depuis un autre "package".
Si le programme est défini par une classe sans public
,
la commande Unix java
que l'on utilise pour lancer l'application
ne pourra pas faire référence à la classe, et donc
ne pourra pas lancer le programme!
De même, si cette classe MaBelleClasse
est bien
définie avec public
, mais si sa méthode
main
n'est pas définie avec public
,
la commande java
ne pourra pas faire référence
à MaBelleClasse.main
.
Comme on ne cherche pas à référencer d'autres
méthodes à l'extérieur de la classe, il n'est pas
nécessaire de les déclarer publiques.
De même, tant que l'on ne cherche pas à écrire
plusieurs package, il n'est pas nécessaire de déclarer
une classe publique.
En plus de cette règle, le compilateur javac
exige qu'il
n'y ait qu'une seule classe publique dans le fichier à compiler, et que
celle-ci porte le même nom que le fichier, d'où la règle 1.
Moralité: n'utiliser public
que pour la classe
principale, et pour les méthodes devant être rendues accessibles
d'une classe à une autre (règle 2).
static
signifie que l'on n'a qu'une adresse fixe et non une
adresse par instanciation.
Dans le cas d'une méthode, si l'on n'utilise pas static
,
la méthode dépend de l'instanciation de la classe:
par exemple, la classe String
admet une méthode
public int length();Si l'on a un objet
str
de type String
, celui-ci
instancie la classe String
, et l'on a alors accès
à la méthode str.length()
qui retourne un entier
(qui est la longueur de la chaîne str
).
Les méthodes déclarées sans static
s'appellent des méthodes d'instance.
En revanche, si l'on utilise static
pour déclarer une
méthode (on les appelle des méthodes de classes),
elle ne dépend plus d'une instanciation de la classe.
Par exemple, la classe String
admet une méthode
public static String valueOf(int i);que l'on peut appeler par
String.valueOf(i)
.
(Cela crée une chaîne qui représente l'entier
i
.)
De même, la classe Math
admet une méthode
public static int abs(int a);qui permet de calculer la valeur absolue de
x
par
Math.abs(x)
.
La classe Integer
admet une méthode
public static int parseInt(String str);qui permet de décoder une chaîne
str
qui
représente un entier en cet entier par
Integer.parseInt(str)
.
int[] tab; tab=new int[100];les éléments sont
tab[0]
, ..., tab[99]
.
On peut se passer d'utiliser tab[0]
en commençant
à tab[1]
, mais ce n'est pas très
élégant.
En revanche, si l'on essaye d'accéder à tab[100]
,
on aura une exception qui arrêtera le programme sur un message
d'erreur.
Il est recommandé de définir un tableau dont la taille correspond
exactement à ce qui est utilisé pour éviter de donner
l'impression que l'on ne maîtrise pas la dimension des tableaux.
.class
et .java
MaBelleClasse.java
.
Ce fichier doit contenir la définition d'une classe
public MaBelleClasse
.
On compile ce programme par
javac MaBelleClasse.javaqui crée un fichier
MaBelleClasse.class
.
(D'autres fichiers .class
peuvent être créés
s'il y a d'autres classes définies dans le fichier.)
Les fichiers .class
contiennent du code dans le language de la
machine virtuelle Java.
Ils sont illisibles au commun des mortels.
Donc, lorsque l'on transmet un programme Java, il vaut mieux envoyer le
fichier source .java
.
|
et ||
,
&
et &&
|
et ||
effectuent un
ou logique (que l'on note OR).
L'opération |
prend deux entiers et effectue un OR
bit-à-bit et retourne un entier.
Par exemple 9|3
vaut 11
car 9 vaut 1001, 3 vaut 0011,
11 vaut 1011 et
1001 | 0011 ---- 1011En revanche, l'opération
|
prend deux boolean
et retourne le OR des deux.
Par exemple, true || false
vaut true
.
De même, les opérations &
et &&
effectuent un et logique (que l'on note AND).
Dans un test (par exemple, dans une structure if
), il faut
employer ||
et &&
(de la même manière que l'on emploie ==
).
Les opérations
Pour les tableaux a deux dimensions, on peut définir un tableau de
pointeurs sur des tableaux par
|
et &
peuvent
également s'appliquer à des boolean
.
Il y a cependant une légère différence, car
|
et &
évaluent systématiquement
leurs deux arguments.
En revanche, &&
par exemple n'évalue pas le second
argument si le premier est false
.
Cela permet d'écrire
(i>=0)&&(tab[i]!=0)
.
(Avec un &
, si tab[i]!=0
serait également évalué,
ce qui conduirait à une erreur.)
Lorsque l'on déclare un tableau par
int [] tab;
on crée un identificateur tab
qui vaut null
.
Si l'on tente de lire à tab[4]
, on provoque une erreur.
On doit préalablement initialiser le tableau par
tab=new int[100];
On effectue communément les deux instructions simultannément par
la syntaxe
int [] tab=new int[100];
int [][] tab;
On peut l'initialiser par
tab=new int[100][50];
On peut également définir la dimension du premier tableau avant
de définir celle des autres par
tab=new int[100][];
Dans ce cas, on peut accéder au tableau tab[5]
qui vaut
null
au départ, car il n'est pas initialisé.
On l'initialise par
tab[5]=new int[50];
mais cela ne préjuge en rien de tab[14]
.
On a ainsi tab[5].length
qui vaut 50
,
tab.length
qui vaut 100
...
Lorsque l'on a trois variables a
, b
et c
de type int
et que l'on effectue
c = a / b
on place dans c
la partie entière de la division de
a
par b
.
En particulier
int x;
x = 5 / 2;
x = x * 2;
System.out.println(x);
donne le résultat 4
.
La méthode System.out.println
ne permet d'afficher que
des types élémentaires ou le type String
.
En particulier,
int[] tab={0,1,2,3};
System.out.println(tab);
affiche le contenu de la variable tab
, soit un pointeur vers
un objet composé de type "tableau d'entiers".
Cela n'affiche donc pas le contenu du tableau mais une adresse mémoire
qui contient le tableau.
La longueur d'un tableau .length
et .length()
tab
s'obtient par
tab.length
, car length
est déclaré
comme variable d'instance dans une classe qui représente les
tableaux.
En revanche, la longueur d'une chaîne de caractères
str
s'obtient par str.length()
(avec des parenthèses vides), car length
est
déclaré comme méthode d'instance de la classe
String
, que l'on appelle donc avec une liste vide d'arguments.
Si l'on a deux objets String
a
et b
de type
String
, il n'est pas possible de les comparer par
a==b
.
En effet, comme String
est un type composé, ses instances
ne sont en fait que des références vers des cellules de
mémoire, et a==b
teste si l'on a la même
référence et non la même chaîne.
Pour les comparer, il faut utiliser a.equals(b)
.