Déclaration d'une classe:
class Person { String name = "namePers"; int age; void growUp() { age ++; } } |
Les déclarations de variables et de
méthodes
peuvent apparaître dans n'importe quel ordre, mais lors de
l'initialisation
des variables, on ne peut pas utiliser des références
à
des variables pas encore déclarés.
Pour créer des variables (instances) de la
classe Pendule:
Person p1, p2;
Chaque langage a ces moyens propres de manipuler les données. En Java chaque instance de classe est toujours une référence à un objet. On peut imaginer l'objet comme une poste de télévision et son nom – comme un contrôle à distance. Les instances p1 est p2 de la classe Person représentent des variables qui référencent des objets de type Person mais les objets ne sont pas encore crée et les variables sont "vides" - ne pointent pas sur un objet réel. Pour pouvoir utiliser ces variables il faut créer dynamiquement les objets en "heap" en utilisant le mot - clé new:
p1 = new Person ();
p2 = new Person ();
p2.age =
21;
p1.growUp();
Chaque objet possède son propre jeu de membres – données
Comme les membres–donnée, les méthodes sont associées à une objet. Mais chaque objet ne possède pas sa propre copie de la méthode. En effet il n'existe qu'un seule copie de la méthode, mais qui travaille avec les membres – données d'un objet particulier.
Pour pouvoir faire ça, chaque méthode (à l'exception des méthodes statiques) reçois un paramètre implicite (on ne le voit pas) this qui représente un référence vers l'objet concerné et qui est ajouté automatiquement chaque fois quand on utilise un membre – donnée. Ainsi l'instruction
age++;
est interprété comme:
(this.age)++;
On peut utiliser se paramètre aussi bien,
explicitement
dans le corps de méthode.
L'affectation entre deux objet a pour résultat deux références qui pointent sur le même objet:
class Number {
int i;
}
public class Assignment {
public static void
main(String[]
args) {
Number n1 = new Number();
Number n2 = new Number();
n1.i = 9;
n2.i = 47;
System.out.println("1: n1.i: " + n1.i +", n2.i: " + n2.i);
n1 = n2;
System.out.println("2: n1.i: " + n1.i + ", n2.i: " + n2.i);
n1.i = 27;
System.out.println("3: n1.i: " + n1.i + ", n2.i: " + n2.i);
}
}
Résultat:
1: n1.i: 9, n2.i: 47
2: n1.i: 47, n2.i: 47
3: n1.i: 27, n2.i: 27
les opérateur relationnels '= =' et '!=' ne testent pas les objets mais leur références:
public class Equivalence {
public static void
main(String[]
args) {
Integer n1 = new Integer(47);
Integer n2 = new Integer(47);
System.out.println(n1 == n2); //compare des références -
faux
System.out.println(n1 != n2); //compare des références -
vrai
}
}
A chaque type primitif correspond une classe ("wrapper class") qui permet la création des objets pour présenté se type primitif:
char c
=
'd';
Character
C = new Character(c);
ou bien
Character C = new Character('d');
Java 1.1 a ajouté deux classe pour
arithmétique
de haute précision – BigInteger et BigDecimal.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Number
à la
place de type primitif::
MIN_VALUE
ou bien MAX_VALUE
.exemple | resultats |
import java.math.BigInteger; public class WrappedClassApp { static final int radix = 16; public static void main(String args[]) { Boolean b1 = new Boolean("TRUE"); Boolean b2 = new Boolean("FALSE"); System.out.println(b1.toString()+" or "+b2.toString()); for(int j=0;j<radix;++j) System.out.print(Character.forDigit(j,radix)); System.out.println(); System.out.print("Radix between "+ Character.MIN_RADIX); System.out.println(" and " + Character.MAX_RADIX); Integer i = new Integer(Integer.parseInt("ef",radix)); Long l = new Long(Long.parseLong("abcd",radix)); long m=l.longValue()*i.longValue(); System.out.println("radix=4: "+Long.toString(m,4)); System.out.println("radix=10: "+Long.toString(m,10)); System.out.println("radix=16: "+Long.toString(m,16)); System.out.println(Float.MIN_VALUE); System.out.println(Double.MAX_VALUE); BigInteger n=new
BigInteger("1000000000000"); |
true or false 0123456789abcdef Radix between 2 and 36 radix=4: 220012101203 radix=10: 10511459 radix=16: a06463 1.4E-45 1.7976931348623157E308 1000000000039 is probably prime. |
A l'intérieur d'une classe, on peut accéder à tous les membres – données et appeler des méthodes directement par leur nom (accès direct).
L'accès aux membres - données et aux méthodes à l'extérieur des classes Java dépend des modificateurs d'accès. Ces modificateurs définissent divers degrés d'accès aux membres des classes. Les modificateurs d'accès sont indiqués juste avant le type de la variable ou de résultat pour les méthodes. Il existe quatre modificateurs d'accès: par défaut(pas de modificateur), public, protected et private:
par défaut (il n'y a pas de modificateur): seuls les classes de même paquetage peuvent accéder aux membres.
public: les membres sont accessibles à tous, que ce soit à l'intérieur ou à l'extérieur de la classe ou du paquetage:
protected: les membres ne sont accessibles qu'aux méthodes dans cette classe et dans les classes dérivés de cette classe ou du paquetage.
private: les membres ne sont accessibles
qu'aux
méthodes dans la classe où ils ont été
définis
(accès direct).
Access Levels Modifier Class Package Subclass World public
Y Y Y Y protected
Y Y Y N no modifier Y Y N N private
Y N N N
Example:
|
|
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; public class Gama { 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); error //System.out.println (alpha.friend); error System.out.println (alpha.getFriend()); } } |
class Exemple {
int m3=1;
static int m2=3;
static void func() {
Exemple e1 = new Exemple();
Exemple e2 = new Exemple();
int k = m2; //l'accès direct
int n = e1.m3; //l'accès par la référence d'un
objet
…
}…
}
Quand on déclare un membre - donnée comme étant static, on ne lui alloue de la mémoire qu'une seule fois, indépendamment de nombre d'objets effectivement instanciés.
Tous les objets de la classe partagent le même membre static. Une méthode static est une méthode qui ne reçoit pas this comme paramètre, donc elle n'a accès direct qu'aux membres statiques. Pour l'accéder à une membre non static elle doit utiliser la référence d'un objet de la classe.
Les modificateurs final, synchronized et native
final: spécifie qu'une membre – donnée a une valeur constante (initialisée au moment de sa déclaration) ou qu'une méthode ne peut pas être redéfinie dans un sous-classe. Pour ainsi dire, final indique qu'un membre d'une classe est dans sa version définitive.
synchronized: spécifie qu'une méthode est "mono-thread". A un moment donné, une seule exécution est autorisée pour une méthode synchronized.
native: spécifie que la méthode est implémenté en C et se trouve dans un fichier exécutable. Les déclaration de la méthode n'a pas un corps:
native int Cprogramme();
La déclaration d'un tableau se fait à l'aide d'une paire de crochets:
int
nombre[
];
long
grille
[ ], jours [ ];
En différence de C, les tableaux de langage Java sont des objets de la classe tableau. Ces déclarations n'introduisent que des références des tableaux et n'allouent aucune place dans la mémoire, donc on ne peut pas indiquer le nombre des élément dans la déclaration. A fin d'allouer la place pour ces tableau, soit on doit utiliser l'opérateur new:
int nombre[ ] = new int[10]; //un tableau de dix éléments
soit on doit affecter une série d'éléments au tableau au moment de sa création:
char voyelle[ ] = {'a', 'e', 'i', 'o', 'u'}; // un tableau de cinq éléments
La taille d'un tableau est disponible grâce à la variable publique length:
int longueur = voyelle.length; //longueur = 5
Esayer d'acceder à un élément qui est à l'extérieur du tableau génère une exception ArrayIndexOutOfBoundsException de type RuntimeException.
La méthode arraycopy() de la classe System sert pour copier un certain nombre d'éléments d'un tableau dans un autre:
System.arraycopy (objetsSource, positionSource, objetdDestination, positionDéstination, longueur)
Par exemple pour ajouter un élément aux tableau voyelle:
char
voyelle[
] = {'a', 'e', 'i', 'o', 'u'};
char tmp[
] = new char[voyelle.length+1];
System.arraycopy(voyelle,
0, tmp, 0, voyelle.length);
tmp[voyelle.lemgth]
= 'y';
voyelle=tmp;
Il n'y a plus de références sur l'ancien objet et il sera récupéré par le ramasse-miette
Pour parcourir complètement ou partiellement un tableau,
il suffit simplement d'utiliser une boucle for
. Voici un
exemple qui parcoure complètement un tableau pour l'afficher
à la console :
public class Array{ public static void main(String a[]){ int ar[] = {-3,4,-17,2,-1,8}; for(int i =0; i< ar.length;i++){ System.out.println(" "+ar[i]); } } } |
-3 4 -17 2 -1 8 |
Il ne faut pas oublier que le premier indice du tableau est 0,
ensuite on parcoure toutes les positions jusqu'à atteindre tab.length
- 1
.
Java 5.0 offre une nouvelle boucle for
qui permet de facilement parcourir tous les objets qui
représentent des
collections d'objets. Le listing suivant donne la syntaxe de cette
boucle for
.
for
(<type_de_donnée> <nom_variable> :
<collection_à_parcourir>)
{
// Corps de la boucle
}
public class Array{ public static void main(String a[]){ int ar[] = {-3,4,-17,2,-1,8}; for(int el :ar){ System.out.println(" "+el); } } } |
-3 4 -17 2 -1 8 |
Java gère les tableaux à plusieurs dimensions avec des objets qui sont des tableaux de tableaux. La syntaxe est ressemblant à celle de C:
int
matrice
[ ] [ ];
matrice
= new int [8][8];
matrice[0][0]
= 3;
matrice
[0][1] = 5;
…
On peut créer des tableaux dont les lignes n'ont pas forcément la même taille:
int
ex[][]
= new int[3][ ];
ex[0] =
new int [3];
ex[1] =
new int[5];
ex[2] =
new int[4];
|
|
|
||
|
|
|
|
|
|
|
|
|
Example
public class Array{ public static void main(String a[]){ int ar[][] = {{3,4},{17,2,1,8}}; for(int i =0; i< ar.length;i++){ for(int j = 0;j< ar[i].length; j++) System.out.print(" "+ar[i][j]); System.out.println(); } } } |
3 4 17 2 1 8 |
public class Array_s { public static void main(String a[]){ String ar[][] = {{"Koko","Kiko","Kako"},{"Simo", "Sima"}}; for(String[] line :ar){ for(String el:line) System.out.print(" "+el); System.out.println(); } } } |
Koko Kiko Kako Simo Sima |
Une
collection Liste
ne peut contenir que des objets.
Il
existe deux implémentations de liste à
usage général
- ArrayList et
LinkedList. Le plus
utilisée, est ArrayList.
Il
offre un accès
en
temps constant de
position,
et il peut profiter de System.arraycopy quand
il doit déplacer
plusieurs
éléments en
même temps.
List<Object> listOfObjects = new ArrayList<Object>();
class Person{
...
}
class Student extends Person{
...
}
List<Person> listOfPersons = new ArrayList<Person>();
Utilisation
import
java.util.*; public class ListDemo { public static void main(String args[]) { // Create an array list ArrayList <String> al = new ArrayList <String>(); System.out.println("initial size:"+al.size()); // add elements to the array list al.add("C"); al.add("A"); al.add("E"); al.add("B"); al.add("D"); al.add("F"); System.out.println("the new size:"+al.size()); for(int i = 0; i <al.size(); i++){ System.out.println(al.get(i)); } String ex = al.remove (2); System.out.println("removing value:"+ex); System.out.println("size after remove:"+al.size()); for(int i = 0; i <al.size(); i++){ System.out.println(al.get(i)); } } } |
initial size:0 the new size:6 C A E B D F removing value:E size after remove:5 C A B D F |
Iterateurs
import
java.util.*; public class IteratorDem { public static void main(String arg[]){ // Create an array list ArrayList <String> al = new ArrayList <String>(); // add elements to the array list al.add("C"); al.add("A"); System.out.println("ArrayList:"+al.get(0)+" "+al.get(1)); ListIterator<String> litr = al.listIterator(); // litr.set("new"); error- there is no element in the iterator System.out.println("before element "+litr.nextIndex()); System.out.println("after element "+litr.previousIndex()); System.out.println(litr.next()); System.out.println("before element "+litr.nextIndex()); System.out.println("after element "+litr.previousIndex()); litr.set("modified"); // modify the last element returned // by next() or previous() System.out.println("ArrayList:"+al.get(0)+" "+al.get(1)); } } |
ArrayList:C A before element 0 after element -1 C before element 1 after element 0 ArrayList:modified A |
import
java.util.*;
public class IteratorDemo {
public static void main(String args[]) {
// Create an array list
ArrayList <String> al = new
ArrayList <String>();
// add elements to the array list
al.add("C");
al.add("A");
al.add("E");
al.add("B");
al.add("D");
al.add("F");
// Use iterator to display contents of al
System.out.print("Original contents of
al: ");
Iterator<String> itr =
al.iterator();
while(itr.hasNext()) {
String element =
itr.next();
System.out.print(element + " ");
}
System.out.println();
// Modify objects being iterated
ListIterator<String> litr =
al.listIterator();
while(litr.hasNext()) {
String element =
litr.next();
litr.set(element +
"+");
}
System.out.print("Modified contents of
al: ");
itr = al.iterator();
while(itr.hasNext()) {
String element =
itr.next();
System.out.print(element + " ");
}
System.out.println();
// Now, display the list backwards
System.out.print("Modified list
backwards: ");
while(litr.hasPrevious()) {
String element =
litr.previous();
System.out.print(element + " ");
}
System.out.println();
}
}
En Java le chaînes sont gérées par une classe spécifique appelée "String". Même les littéraux de type chaîne sont géré de façon interne comme des objets de cette classe.
Les chaînes de caractères sont inaltérables: une fois créé un objet String on ne peut pas changer sa valeur. Les opérations qui permettent de changer les caractères ou la taille d'une chaîne renvoient un nouvel objet String.
String chaine =
"exemple
de création une chaîne";
int longueur =
chaine.length();
String concatenation
= "Pierre" + " et Marie";
On peut construire un objet String d'un tableau de caractères ou d'un tableau de nombres:
class CreateString{ public static void main(String[] a){ char datac[ ] = {'p', 'a', 'r', 'c'}; String sc = new String(datac); //tableau entier byte datad [ ] = {65,66,67}; //'A','B', 'C' String sd = new String(datad, 0,3); //tableau, debut, longuer byte datao [ ] = {065,066,067,064}; //'5', '6', '7', '4' String so = new String(datao, 0,3); byte datah [ ] = {0x65,0x66,0x67}; // 'e', 'f', 'g' String sh = new String(datah, 0,3); System.out.println(" c:"+sc+ "\n 8:"+so+"\n 10:"+sd+"\n 16:"+sh); } } |
c:parc 8:567 10:ABC 16:efg |
La méthode statique String.valueOf() permets la conversion des types différents sous la forme d'une chaîne de caractères.
String one = String.valueOf(1);
Tous les objets Java possèdent une méthode toString() héritée de la classe Objet qui est utilisée par String.valueOf() pour la présentation sous forme de chaîne.
Conversion à partir d'une chaîne
Pour faire cette conversion on utilise les méthodes valueOf() qui sont fournit par les classes enveloppes (wrapper):
int i
=
Integer.valueOf("126").intValue();
//racine = 10
float f
=
Float.valueOf("14.75").floatValue();
//racine = 10
int k =
Integer.parseInt("234");
//racine = 10
int j =
Integer.parseInt("ef",racine);
long l
= Long.parseLong("abcd",racine);
racine - le racine du systeme dont la valeur est entre Character.MIN_RADIX et Character.MAX_RADIX (2 et 32).
Examples:
parseInt("0",
10)
-> 0
parseInt("473",
10)
-> 473
parseInt("-0",
10)
-> 0
parseInt("-FF",
16)
-> -255
parseInt("1100110",
2)
-> 102
parseInt("2147483647", 10) -> 2147483647
parseInt("-2147483648", 10) -> -2147483648
parseInt("2147483648", 10) jette une
NumberFormatException
parseInt("99",
8)
jette une NumberFormatException
parseInt("Kona",
10)
jette une NumberFormatException
parseInt("Kona",
27)
-> 411787
On ne peut pas utiliser les opérateurs relationnels.
méthode equals(), equalsIgnoreCase(), compareTo().
String un = "truc";
String deux = "truc";
String trois = "TRUC";
if (un ==
deux)
//faux
if(un.equals(deux))
//vrai
if
(un.equalsIgnoreCase(trois))
//vrai
if(un.compareTo(trois)
> 0) //vrai
if(un.compareTo(deux)
==0) //vrai
Exemple
public class stringExem{ public static void main(String a[]){ String names [ ] = {"Rose","Anabelle", "Gerard", "Francoise", "Erik","Constance"},name; for(boolean ok = false; !ok; ){ ok=true; for(int i = 0; i < names.length-1; i++){ if(names[i].compareTo(names[i+1])>0){ name = names[i]; names[i] = names[i+1]; names[i+1] = name; ok = false; } } } for(int i = 0; i <names.length;i++) System.out.println (names[i] + " : "+names[i].length()+" lettres"); } } |
Anabelle : 8 lettres Constance : 9 lettres Erik : 4 lettres Francoise : 9 lettres Gerard : 6 lettres Rose : 4 lettres |
Cetains méthodes utiles:
public char charAt(int index)
public boolean endsWith(String suffix)
public int indexOf(String str)
public int indexOf(String str,int fromIndex)
public int lastIndexOf(String str)
public String replace(char oldChar,char newChar)
public boolean startsWith(String prefix)
public String substring(int beginIndex)
public String substring(int beginIndex,int endIndex)
public String toUpperCase()
public String toLowerCase()
public String trim()