Compléments en programmation Java

publicité
Compléments
Chapitre III
(~70 transparents)
1
Au sommaire de ce chapitre
1. Les fichiers ----------------- 3
2. Les classes utilitaires ----- 29
3. La généricité --------------- 49
4. Autres API java, compilation JIT
et archive jar ------------ 60
2
1 – Les fichiers
3
Les flux
• Java propose un ensemble de classes pour
la gestion des E/S décrites dans le package
java.io
– les E/S sont implémentées par les flux (stream)
• Un flux est tuyau de transport séquentiel de
données
• Il existe un flux par type de données à transporter
4
Les flux (suite)
• Un flux est unidirectionnel
5
Deux familles de flux
• Les flux de caractères (caractères sur 16 bits)
– dans un flux texte les données sont stockées sous
forme de caractères sur le disque, et non sous forme
d’octets
• il y a donc une transformation qui est effectuée entre
mémoire et disque
• Les flux d'octets (informations binaires sur 8
bits)
– dans un flux binaire aucune transformation n'est
effectuée sur les octets échangés
6
Flux d’octets en entrée
3 Classes utilisées pour la communication
lecture de fichiers octets par octets
récupère des données provenant d'un
flux de sortie
(cf. PipedOutputStream)
lit des données dans un tampon
structuré sous forme d'un array
Classe abstraite
7
Flux d’octets en entrée
4 Classes utilisées pour le traitement
concaténation d'une énumération de
plusieurs flux d'entrée en un seul
flux d'entrée
lecture d'une String (mais Sun
déconseille son utilisation et
préconise son remplacement par
StringReader)
lecture d'objets Java « lisibles »
lit à partir d'un InputStream
quelconque des données, en "filtrant"
certaines données
8
Flux d’octets en sortie
3 Classes utilisées pour la communication
écriture de fichiers octets par octets
Envoi de données sur un flux d’entrée
écrit des données dans un
tampon structuré sous forme
d'un array
Classe abstraite
9
Flux d’octets en sortie
2 Classes utilisées pour le traitement
écriture d'objets Java lisibles
avec ObjectInputStream
.writeObject()
écrit à partir d'un OutputStream
quelconque des données, en
"filtrant" certaines données
10
Les classes des flux caractères
• La hiérarchie des classes relatives aux E/S
de caractères comprend 2 classes abstraites
– Abstract Reader Class : lecture sur les
flots caractères
– Abstract Writer Class : écriture sur les
flots caractères
11
Les classes d'E/S
• A cela il faut rajouter aussi comme classes
de base :
–File : fichier
–RandomAcessFile : accès aléatoires sur un
fichier
12
Sérialisation-Désérialisation
• Parmi tous les mécanismes d'E/S proposés par
Java, le plus intéressant est la sérialisation qui
permet :
– de sauvegarder des objets dans un fichier
– (désérialisation : restaurer des objets à partir d'un
fichier)
• Deux classes du package java.io sont utilisées
– ObjectOutputStream pour la sérialisation
– ObjectInputStream pour la desérialisation
 flux binaires
13
La sérialisation
• Pour écrire le tampon dans le flux, on appelle la
méthode writeObject()
– la classe de l'objet qui effectue la sérialisation doit être
public (souvent, c’est le main)
– la classe de l'objet sérialisé doit implémenter l’interface
Serializable
• Cette méthode appelle également la méthode
writeObject() de chaque objet composite
– si leur classe implémente l'interface Serializable
– et jusqu'à ce que tout ce qui compose l'objet soit écrit
14
Premier exemple
FileOutputStream fos = new
FileOutputStream("t.tmp");
ObjectOutputStream oos = new
ObjectOutputStream(fos);
oos.writeInt(12345);
oos.writeObject("Today");
oos.writeObject(new Date());
oos.close();
15
Exemple : sérialisation d’un objet
import java.io.*;
public class SerializerPersonne {
public static void main(String argv[]) {
Personne unePersonne = new Personne("Dupond","Jean",175);
try {
FileOutputStream fichier = new
FileOutputStream("personne.ser");
ObjectOutputStream oos = new ObjectOutputStream(fichier);
oos.writeObject(unePersonne);
oos.flush(); // pour forcer le tampon à se vider dans le fichier
oos.close(); // on ferme le tampon pour terminer l’opération
}
catch (IOException e) {
e.printStackTrace();
}
Une exception de type IOException peut être levée
} // de main()
si un problème intervient avec le fichier
}
16
Le fichier obtenu
• Après l'exécution de cet exemple, un fichier
nommé « personne.ser » est créé
• On peut visualiser son contenu mais
surtout pas le modifier car sinon il serait
corrompu
• En effet, les données contenues dans ce
fichier ne sont pas toutes au format
caractères
– Fichiers binaires : les valeurs numériques sont
codées en binaire
17
L'interface Serializable
• Cette interface ne définit aucune méthode
– mais permet simplement de marquer une
classe comme pouvant être sérialisée
(cf. Cloneable)
• Elle est définie dans java.io
• Si l'on tente de sérialiser un objet qui
n'implémente pas l'interface Serializable
– une exception NotSerializableException
est levée
18
La dé-sérialisation
• Classe java.io.FileInputStream
– Un FileInputStream est un flux d’octets en
entrée pour lire des données à partir d'un
fichier
– FileInputStream est une sous-classe de
InputStream
• Classe java.io.ObjectInputStream
– Un ObjectInputStream est un tampon qui lit
des données (en octets: type primitif et objets)
19
à partir d’un InputStream
Processus de dé-sérialisation
• Il est un tout petit peu plus complexe…
• Pour remplir un tampon de lecture à partir d'un
fichier, on appelle la méthode readObject()
– cette méthode renvoie une référence sur Object
– il faut donc effectuer un transtypage
• Si on ne connaît pas la classe d'appartenance d'un
objet (parmi plusieurs possibles)
– on récupère la classe par les méthodes getName()et
getClass() de la classe Class
– exemple :
if (monObjet.getClass().getName().equals(MaClasse)
20
Désérialisation du premier exemple
FileInputStream fis = new
FileInputStream("t.tmp");
ObjectInputStream ois = new
ObjectInputStream(fis);
int i = ois.readInt();
String today = (String) ois.readObject();
Date date = (Date) ois.readObject();
ois.close();
21
Ex. : dé-sérialiser une Personne
public class DeSerializerPersonne {
public static void main(String argv[]) {
try {
FileInputStream fichier = new
FileInputStream("personne.ser");
ObjectInputStream ois = new ObjectInputStream(fichier);
Personne someOne = (Personne) ois.readObject();
System.out.println("Personne : ");
System.out.println("nom : "+ someOne.getNom());
System.out.println("prenom : "+ someOne.getPrenom());
System.out.println("taille : "+ someOne.getTaille());
}
catch (java.io.IOException e) {
e.printStackTrace();
ici on sait que
}
l’objet lu est
catch (ClassNotFoundException e) {
e.printStackTrace();
de type
}
Personne
} // de main()
}
22
Ex. 2 : sérialisation d’un tableau
import java.io.*; // illustration de la sérialisation
class TestSerialisation {
public static void main (String argv[ ]) {
Compte[] tabcpt = new Compte [3]; // on crée un tableau de 3 comptes
tabcpt[0] = new Compte("tartempion", 3500);
tabcpt[1] = new Compte("dupond", 1000);
tabcpt[2] = new Compte("martin", 7500);
try { // sérialisation
// ouverture du fichier
String nomFic = "FCOMPTE.TMP"; // nom du fichier
File f1 = new File(nomFic); // déclaration d'un fichier
// définition d'un flot de sortie et écriture :
FileOutputStream fs = new FileOutputStream(f1);
ObjectOutputStream fsObj = new ObjectOutputStream(fs);
fsObj.writeObject(tabcpt); // on écrit tout le tableau
fsObj.close();
// on ferme le flot
23
Exemple 2 : dé-sérialisation
System.out.println("\n Lecture du fichier\n");
// définition d'un flot en lecture
FileInputStream fe = new FileInputStream(f1);
ObjectInputStream feObj = new ObjectInputStream(fe);
// on lit le flot et on récupère dans un tableau
Compte table[] = (Compte []) feObj.readObject();
// affichage des résultats
for (int i=0; i < table.length; i++) {
table[i].affiche();
System.out.println("\n");
}
feObj.close();
// on ferme le flot
}
catch (Exception e) {
e.printStackTrace();
System.out.println("\n "+e.getMessage()+"\n ");
}
}
} // fin de TestSerialisation
24
Exemple 2 : la classe Compte
// extrait de la classe Compte
class Compte implements Serializable
{
private static int numeroAttribue = 0;
// attributs de la classe
private int numeroCompte;
private String nomCompte;
private float soldeCompte;
Compte(String nom, float solde)
{
numeroCompte = ++numeroAttribue;
nomCompte = new String (nom);
soldeCompte = solde;
}
public void affiche()
{
System.out.println(" - Numero...: "+numeroCompte);
System.out.println(" - Nom......: "+nomCompte);
System.out.println(" - Solde....: "+soldeCompte);
}
...
} // fin de la classe Compte
25
A noter…
• La classe ObjectInputStream possède
toutes les méthodes pour lire des données
de type primitif :
– readInt(), readDouble(), readFloat ...
• Lors de la déserialisation, le constructeur
de l'objet n'est jamais utilisé
26
Précisions sur les exceptions
• Une classe peut effectuer un traitement
durant la sérialisation ou désérialisation en
implémentant les méthodes suivantes :
– private void writeObject
(ObjectOutputStream stream)
throws IOException;
– private void readObject(ObjectInputStream
stream)
throws IOException,
ClassNotFoundException;
27
Exceptions possibles
• Si la classe a changé entre le moment où
elle a été sérialisée et le moment où elle
est déserialisée
– L’exception qui est levée est :
java.io.InvalidClassException
• Une exception de type
streamCorruptedException peut être
levée si le fichier a été corrompu
– par exemple en le modifiant avec un éditeur
28
Exceptions possibles (suite)
• Au cours de la déserialisation :
Une exception de type
ClassNotFoundException peut être levée
si l'objet est transtypé vers une classe qui
n'existe plus ou pas au moment de
l'exécution.
– Par ex. si on renomme Personne.class
29
Précisions (suite)
• Lorsqu'un attribut d'une classe ne doit pas être sérialisé
il faut le déclarer transient
– Le contenu des attributs sont invisibles dans le flux dans lequel
est sérialisé l'objet.
– Il est ainsi possible pour toute personne ayant accès au flux de
voir le contenu de chaque attribut même si ceux si sont
private :
– Ex. :
private transient String codeSecret;
– Attention lors de la déserialisation, les champs transient sont
initialisé avec la valeur null !
• Un attribut static n'est pas sérialisé
• Les sous-classes d'une classe sérialisable le sont
également
30
2 – Les classes utilitaires
31
Classes utilitaires
• Composants du package java.util fournis
– sous forme de classe
– ou sous forme d'interface
• Quelques exemples
– classes conteneurs Vector, Stack, HashMap
– classes outils Random, Date
– interfaces Collection Iterator Observer
32
La classe Vector
• Cette classe définit un conteneur de type
tableau dynamique
– il s'agit d'une collection d'objets de type
quelconque
– à laquelle on peut accéder soit par un index soit
par un itérateur
– la classe Vector implémente l'interface List ce
qui permet de l'utiliser comme une liste
– les instances stockées peuvent être des objets de
classes différentes
33
Le vector est une liste abstraite
Object
public class Vector
AbstractCollection
extends AbstractList
implements List, RandomAccess,
Cloneable, Serializable
AbstractList
Vector
34
Constructeurs de la classe Vector
 Vector() //crée un vecteur vide
 Vector(int capacitéInitiale)
// crée un vecteur vide de capacité initialCapacité
 Vector(int capacitéInitiale, int
incrémenteCap
)
// crée un vecteur vide et un facteur d'accroissement spécifié
protected int capacityIncrement : attribut de Vector, = valeur avec
laquelle la capacité du vector est automatiquement incrémentée
lorsque la taille du vecteur dépasse sa capacité initiale
 Permettre l’optimisation de la gestion mémoire
(consulter la documentation java)
35
Classe Vector
• Principales méthodes supportées:
– ajout, insertion, suppression, recherche,
extraction d'un élément
Quelques méthodes de Vector
•
Insertion d'un élément
 boolean add(Object o)
// ajoute l'élément à la fin du vecteur

void add(int Index, Object element)
// insère l'élément donné en position donnée
36
Quelques méthodes de la classe Vector
•
Recherche - information
 Object get(int index)


// renvoie l'élément situé à la position indiquée
int indexOf(Object element)
// recherche la première occurrence d'un élément- surcharge
// nécessaire de la méthode equals / critère de recherche
int size()
// renvoie le nombre de composants du vecteur
•
Suppression - Modification
 Object remove(int index)
// supprime l'élément situé à la position indiquée

boolean remove(Object o)
// supprime la première occurrence de l'élément donné

void clear()
// supprime tous les éléments du vecteur
37
Quelques méthodes de la classe Vector
•
Conversion d'un vecteur en un tableau


•
Object[] toArray()
Object[] toArray(Object[]tab)
Tri du conteneur
1.
Spécifier que la classe des objets du conteneur
implémente l'interface Comparable
2.
3.
Implémenter la méthode compareTo dans cette classe
Invoquer la méthode sort de la classe Collections
Vector conteneur = new Vector(20,5);
….
Collections.sort(conteneur);
38
Exemple Classe TestPersonnel
type Object
// utilisation de la classe Vector
// définition d'une instance de Vector de 20 éléments et dont
// la capacité est augmentée de 5 si débordement
Vector conteneur = new Vector(20,5);
// on ajoute 2 instances de la hiérarchie Personnel
conteneur.add(new Employe("dupond","poste 2091",20.50f,160));
conteneur.add(new Directeur("BigBoss","top secret",85000,
2500.45f));
// variable temporaire
Personnel temp = new Employe("toto","--",20.50f,160);
// insère l'objet temp en deuxième position dans le conteneur
conteneur.add(1,temp);
// affichage du contenu du vecteur
for (int i=0; i<conteneur.size();i++) {
System.out.println("\n\n Caracteristiques du salarie : ");
System.out.println((Personnel)conteneur.get(i));
}
Transtypage obligatoire
39
Exemple :utilisation d’un itérateur
// définition d'un itérateur
Iterator it = conteneur.iterator();
// affichage du contenu du vecteur par l'iterateur
while (it.hasNext()) {
System.out.println("\n\n Caracteristiques du salarie:");
System.out.println((Personnel)it.next());
}
// conversion du vecteur en un tableau de Personnel
Personnel tabSalarie[] = new Personnel[conteneur.size()];
tabSalarie = (Personnel[])conteneur.toArray(tabSalarie);
// affichage du contenu du tableau
for (int i=0;i<3;i++) {
System.out.println("\nCaracteristiques du salarie : ");
System.out.println(tabSalarie[i]);
}
40
Exemples
// supprimer la référence sur le deuxième élément
conteneur.remove(1);
// ou bien si on veut garder une référence sur l'élément supprimé
Personnel recup = (Personnel) conteneur.remove(1);
System.out.println("\n\n Caracteristiques du salarie
supprime: " + recup);
// pour rechercher l'occurrence d'un élément il faut
// avoir surchargé la méthode equals() pour le type de
// l'élément : ici, dans la hiérarchie Personnel, le
// critère choisi est le nom:
boolean equals(Personnel p) {
return nomPers.equals(p.getNom()); }
dans la classe Personnel
41
Exemple (fin)
// on peut aussi rechercher un objet
dans le conteneur par la méthode
indexOf:
i = conteneur.indexOf(temp);
System.out.println("\n\n le salarie
recherche est à la position: "+i);
42
Exemples
//
//
//
//
dans la classe Personnel
pour trier le conteneur il faut d'abord spécifier que
la classe Personnel implémente l'interface Comparable
et il faut définir ensuite la méthode compareTo()
de la classe Personnel
// ici, on veut trier par le numéro de téléphone :
public int compareTo(Object p) {
return numTel.compareTo(((Personnel)p).numTel);
}
// on effectue le tri du conteneur en invoquant la méthode
sort de la classe Collections
//ATTENTION ne pas confondre avec l'interface Collection
(sans s) !!!
Collections.sort(conteneur);
// pour vider totalement le conteneur
conteneur.clear();
43
Interface Comparable
• Tous les objets qui doivent définir un ordre
utilisé par le tri d'une collection
– doivent implémenter cette interface.
• Cette interface = une seule méthode :
int compareTo(Object)
• Cette méthode doit renvoyer :
- une valeur entière négative si l'objet courant est
inférieur à l'objet fourni
- une valeur entière positive si l'objet courant est
supérieur à l'objet fourni
- une valeur nulle si l'objet courant est égal à l'objet
fourni
44
Interface Comparable
• Les classes wrappers des types de
base =
classes fournissant les méthodes utiles pour
la manipulations de ces types (Integer, Short, Double,
mais aussi String et Date
implémentent l’interface Comparable
etc),
– On peut donc comparer ces objets
• Rappel : Classe Integer ≠ type int
– Integer.parseInt("-240"))transforme la chaîne "-240" en valeur
entière -240
45
Les collections
• Les collections en Java stockent toujours
des références sur les objets contenus
dans la collection et non les objets eux
mêmes
– Ce sont obligatoirement des objets qui
doivent être ajoutés dans une collection
– Il n'est pas possible de stocker directement
des types primitifs : il faut obligatoirement
encapsuler ces données dans des wrappers.
46
Interfaces Java pour les collections
Les interfaces à utiliser par des objets qui gèrent des collections sont :
• Collection : interface qui est implementée par la plupart des objets
qui gèrent des collections.
• Map : interface qui définie des méthodes pour des objets qui gèrent
des collections sous la forme clé/valeur
• Set : interface pour des objets qui n'autorisent pas la gestion des
doublons dans l'ensemble
• List : interface pour des objets qui autorisent la gestion des
doublons et un accès direct à un élément
• SortedSet : interface qui étend l'interface Set et permet d'ordonner
l'ensemble
• SortedMap : interface qui étend l'interface Map et permet
d'ordonner l'ensemble
47
Collections personnalisées
• Le package Java pour les collections
fournit aussi plusieurs classes abstraites
– qui proposent une implémentation partielle
d'une interface pour pouvoir créer une
collection personnalisée :
– AbstractCollection, AbstractList,
AbstractMap,
AbstractSequentialList et
AbstractSet
48
Quelques méthodes de l’Interface
Collection
• boolean add(Object) // ajoute l'élément fourni en
•
•
•
•
paramètre à la collection. La valeur de retour indique si
la collection a été mise à jour
boolean addAll(Collection) // ajoute à la
collection tous les éléments de la collection fournie en
paramètre
void clear() // supprime tous les éléments de la
collection
boolean contains(Object) // indique si la
collection contient au moins un élément identique à celui
fourni en paramètre
boolean containsAll(Collection) // indique si
tous les éléments de la collection fournie en paramètre
sont contenus dans la collection
49
Quelques méthodes de l’Interface
Collection
• boolean isEmpty() // indique si la collection est vide
• Iterator iterator() // renvoie un objet qui permet
•
•
•
•
•
de parcourir l'ensemble des éléments de la collection
boolean remove(Object)
// supprime l'élément fourni en paramètre de la
collection. La valeur de retour indique si la collection a
été mise à jour
boolean removeAll(Collection)
supprime tous les éléments de la collection qui sont
contenus dans la collection fournie en paramètre
int size() // renvoie le nombre d'éléments contenu
dans la collection
Object[] toArray() // renvoie d'un tableau d'objets
qui contient tous les éléments de la collection
50
La Classe COLLECTIONS
• La classe Collections propose plusieurs méthodes de
classe (static)
– qui effectuent des opérations sur des collections
• Ces traitements sont polymorphiques car ils demandent
en paramètre un objet qui implémente une interface et
retourne une collection
– Ex. void copy(List, List) // copie tous les éléments de la seconde
liste dans la première
– Enumaration enumeration(Collection) // renvoie un objet
Enumeration pour parcourir la collection
– Object max(Collection) // renvoie le plus grand élément de la
collection selon l'ordre naturel des éléments
– Object max(Collection, Comparator) // renvoie le plus grand
élément de la collection selon l'ordre naturel précisé par l'objet
Comparator
51
Classe Collections (suite)
• void sort(List) // trie la liste dans un ordre
ascendant selon l'ordre des éléments défini par
l'interface Comparable, qui est donc obligatoire
pour les objets de la liste !!
• void sort(List, Comparator) // trie la
liste dans un ordre ascendant selon l'ordre
précisé par l'objet Comparator
• Si un élément dans la liste n’implémente pas
l'interface Comparable :
– une exception de type ClassCastException est
levée
52
3 – La généricité
(Cette partie sera étoffée avec les
nouveautés de Java5 et les
generics)
53
Rappel sur la généricité
• Problème du typage des données
– chaque type a une représentation interne
particulière
– et un certain nombre d'opérateurs associés
– conséquence: pour une même algorithme
l'implémentation dépend du type
• La généricité vise donc à s'affranchir du type
des données
– classes génériques
– méthodes génériques
54
Java et la généricité
• Pas de mécanisme dédié pour la généricité
– comme en C++ avec les templates
• Cependant en Java :
– toutes les classes héritent implicitement de la classe
Object
– et en pratiquant le transtypage on peut transformer
une instance de Object dans un type voulu
• Ainsi, en définissant un modèle au moyen de la
classe Object
– il est possible de structurer des données de type
quelconque
55
Java et la généricité
• Mais l'absence pour l'instant de template
en Java comporte des limites
• En effet un template est un modèle
générique
– il est expansé lors de son utilisation
– la résolution de la définition appropriée des
méthodes à utiliser est donc faite lors de
l'utilisation du modèle
56
Java et la généricité
• En Java la classe qui traduit le modèle est
compilée, d'où un certain nombre de
problèmes
– dans le cas du clonage la seule méthode
clone connue à la compilation est celle de
Object qui ne fait qu'une copie superficielle
– dans le cas d'une comparaison, tout dépend
dépend de la sémantique de l'objet qui est
inconnue au moment de la traduction
57
Java et la généricité
• Toutefois dans bien des cas le mécanisme
de généricité proposé est satisfaisant
• L'exemple suivant montre l'implémentation
d'une pile
• Il s'agit d'un cas d'école car la classe
stack existe bien évidemment
58
Exemple de classe générique
// classe générique qui implémente par un tableau
// une pile d’objets de type quelconque
class Pile {
// constante de classe
static final int Taille = 128;
// attributs privés
private int dimension;
// taille du tableau
private int sommet;
// sommet de la pile
private Object laPile[]; // le tableau qui gère la pile
// méthode estVide qui indique l'état de la pile
boolean estVide() { return sommet==-1 ? true : false; }
59
Exemple de classe générique
// définition des constructeurs
// constructeur qui génère une exception personnelle
définie par une classe plus loin
Pile(int taille) throws PileException {
if (taille < 0)
throw new PileException("constructeur
incorrect");
laPile = new Object[taille];
sommet = -1;
dimension=taille;
}
// constructeur par défaut qui fait appel au
constructeur précédent avec comme taille de pile
la constante de classe appelée Taille
Pile() throws PileException { this(Taille);
}
60
Exemple de classe générique
// méthode qui empile un élément dans la pile
void empiler(Object elem) throws PileException {
sommet++;
if (sommet >= dimension)
throw new PileException("pile pleine");
laPile[sommet] = elem;
}
// méthode qui retourne l'élément dépilé
Object depiler() throws PileException {
if (sommet < 0)
throw new PileException("pile vide");
return laPile[sommet--];
}
} // fin de la classe Pile
61
Exemple de classe d'exception
// définition d'une classe pour gérer les exceptions
// de la classe Pile
// cette classe hérite de la classe Exception
class PileException extends Exception
{
// ne comprend que des constructeurs
public PileException() {};
public PileException(String s) {
super(s);
};
} // fin classe PileException
62
Exemple d'utilisation
try {
// pile d'objets de 5 instances de la classe Individu
Pile pileIndividus = new Pile(5);
pileIndividus.empiler(new Individu("dupont","jean"));
pileIndividus.empiler(new Individu("durand","pierre"));
System.out.println("\n On depile ");
Individu ind;
for (i=0; ! pileIndividus.estVide(); i++)
{
// transtypage obligatoire
ind=(Individu)pileIndividus.depiler();
ind.affiche();
}
} // fin du bloc try
catch (PileException e) { // gestion de l'exception
System.out.println("\n "+e.getMessage()+"\n\n");
}
63
4- Compléments de
développement
Autres API que l’API standard,
compilateur JIT
et archive jar
64
Les autres API de Java
• Java Enterprise API : interaction entre
Java et les systèmes client-serveur.
• Trois modules :
– JDBC (Java DataBase Connectivity) : interaction
entre Java et les bases de données (connexion à
une base de données, envoi de requêtes SQL ,
réception des résultats).
– Java IDL (Interface Definition Language) :
objets mobiles, compatibles avec OMG IDL
– Java RMI : invocation de méthodes à distance,
pour les applications distribuées
65
Autres API (2)
• Java Commerce API : transactions
commerciales sécurisées sur le Web (carte
de crédit, monnaie électronique, etc.)
• Java Server API : développement de
serveurs intranet ou Internet en Java.
66
Autres API (3)
• Java Media API : ensemble d’API
pour la gestion du multimédia
– Java 2D, Java Telephony, Java Animation,
…
• Java Embedded API : destinée aux
appareils électroniques
–  retour aux sources !
.…
67
Compilateur JIT Just-In-Time
• Traduit les byte-codes en instructions
natives
• Amélioration des performances
• Utile si les mêmes byte-codes sont
exécutés plusieurs fois
• Les JVMs supportent, pour la plupart,
la compilation JIT
68
Fichier d’archive jar
• Les fichiers d’archives java permettent de
déployer et de distribuer très facilement
des bibliothèques de classes java
• L’adjonction à l’archive d’un fichier de
configuration particulier, appelé
manifeste, permet de rendre l’archive
exécutable
– Le manifeste contient les informations
concernant la classe à exécuter au lancement
de l’archive
69
Archive et packages
• Le nom d’une archive « .jar » n’a aucune
•
signification particulière
Ce qui est beaucoup plus important est
l’arborescence interne de l’archive qui doit
respecter les conventions java concernant les
packages
– Si l’archive java ne comporte aucune arborescence
interne c’est que les fichiers qu’elle comporte ne font
partie d’aucun package.
70
• Pour utiliser les bibliothèques contenues
dans une archive java il suffit d’ajouter
l’archive dans le « classpath » du
compilateur « javac » et de la « machine
virtuelle java »
• Le développeur devra ensuite spécifier au
besoin les packages à importer au début
de ses fichiers sources java
71
Exécution d’une archive
• Pour exécuter une archive java, il faut utiliser la
commande suivante
java [options] –jar archive_java.jar [classe_principale]
• Pour les versions 1.1 et antérieures de la machine
virtuelle, il faut utiliser la commande « jre archive_java
archive_java.jar classe_principale »
• Pour les version 1.2 et supérieures de la machine
virtuelle, si l’archive java intègre un manifeste précisant
la classe principale à exécuter, il n’est pas besoin de
préciser celle-ci
72
Construction d’une archive
• Pour créer une archive java, il suffit d’exécuter la
commande
jar -cf nom_archive liste_des_fichiers
– où les différents fichiers de la liste sont séparés par
des espaces
– L’option « c » spécifie que l’on souhaite créer une
archive
– L’option « f » permet d’envoyer le flux dans l’archive
dont le nom est spécifié
– L’option « v », pour verbose, permet de suivre
l’évolution de la création de l’archive
73
Extraction d’une archive
• Pour extraire le contenu d’une archive java, il suffit
d’exécuter la commande :
jar -xf nom_archive
[liste_des_fichiers_à_extraire]
• Bien qu’il n’ait pas été conçu pour cela, le format «
.jar » peut être à l’occasion utilisé pour compresser
des fichiers
– au même titre que le format zip ou rar
• En effet, la commande jar, fournit avec toutes les
distributions du SDK, peut être utilisé sur des
plateformes variées.
74
Ajout d’un fichier texte « manifeste »
• Le manifeste est un fichier texte qui
permet, entre autres, de spécifier la classe
qui sera exécutée lors du lancement d’une
archive.
• Pour définir le manifeste, il suffit d’écrire
un fichier texte et de le passer en
paramètre lors de la création de l’archive
en utilisant l’option « m »
jar -cvmf nom_manifeste nom_archive
liste_des_fichiers
75
Fichier manifeste (2)
• L’ordre de passage des arguments
•
•
«nom_manifeste » et « nom_archive » doit être
le même que l’ordre des options « m » et « f »
Le fichier texte « nom_manifeste » doit être
écrit avec son extension (qui peut être
quelconque puisqu’en réalité, c’est le contenu du
fichier qui sera recopié dans le manifeste de
l’archive).
Le manifeste est créé sous le nom «
MANIFEST.MF » dans un répertoire « META-INF
» se situant à la racine de l’archive.
76
Ecrire un manifeste (3)
• Le manifeste comporte un renseignement par
•
ligne
Chaque ligne est du type :
renseignement : valeur
• Chaque ligne, pour être valide, doit
obligatoirement se terminer par un caractère de
retour à la ligne
– attention donc à ajouter ce caractère à la fin de la
dernière ligne du fichier
77
Informations potentielles d’un
fichier manifeste
• Manifest-Version: 1.0 (le manifeste est conforme aux
•
•
•
•
•
•
•
spécifications 1.0 sur la rédaction des manifestes)
Main-Class: classname (à partir de la version 1.2 du
manifeste, spécifie le nom de la classe à exécuter lors du
lancement de l’archive).
Implementation-Title : "titre du package"
Implementation-Version : "n° de version "
Implementation-Vendor : "organisation vendant le
produit"
Specification-Title : "titre de la spécification"
Specification-Version : "n° de version "
Specification-Vendor : "organisation vendant le produit"
78
Téléchargement