Transcript ppt

Introduction à Java
Laurent Henocque
http://laurent.henocque.free.fr/
Enseignant Chercheur ESIL/INFO France
http://laurent.henocque.perso.esil.univmed.fr/
mis à jour en Février 2008
Licence Creative Commons
Cette création est mise à disposition selon le Contrat Paternité-Partage des
Conditions Initiales à l'Identique 2.0 France disponible en ligne
http://creativecommons.org/licenses/by-sa/2.0/fr/
ou par courrier postal à Creative Commons, 559 Nathan Abbott Way,
Stanford, California 94305, USA.
Avertissement
• Ceci est une présentation rapide de Java
– un « rapide » survol
• Doit conduire à l’envie d’entamer la découverte de Java
–
–
–
–
langage en tant que tel
outil de développement graphique et d’interfaces
immense source de logiciel libre
outil « WEB »
• Tout existe dans la doc en ligne grâce à Javadoc : les
commentaires des sources deviennent de la documentation
Introduction / histoire
• Origine
– années 90 (SUN)
• Objectifs
– développer un langage de programmation portable sur toutes les
plates-formes sans recompiler
– développer un micro langage pour calculettes, pda, téléphones, dont
les applications pourraient être téléchargées par internet
• Explosion
– année 95 : apparition de HotJava : « Browser » WEB capable de
supporter les « applets » (ou appliquettes) Java
– aujourd'hui, apparition des premières applications Java vraiment
opérationnelles (Eclipse, Poséidon, jfig, produits Ilog ...)
Introduction
• Le formidable développement de Java est dû à :
– ses possibilités graphiques, d’IHM et d'interopérabilité
– ses liens avec l’internet
• applets: applications aux droits limités exécutées directement dans les pages
html
• mise en oeuvre de rmi, de corba,
• notions de servlets, d'ejb
• triade Java (Java Server Pages JSP)/PhP/Asp
• un faux ami: javascript: langage de script de bas niveau pour pages HTML
(supporté par les « browsers »)
–
–
–
–
sa gratuité
sa simplicité
les très nombreuses bibliothèques disponibles
les outils (Eclipse)
Java est un langage (1/4)
• orienté objets
– les concepts sont proches de C++, parfois empruntés à smalltalk
– quelques sensibles différences avec C++ en pratique
• simple
–
–
–
–
le comportement par défaut est celui qui est le plus utile
« proche » de la syntaxe du C++
non imprégné de C
« plus de pointeur » (seulement des pointeurs), « plus de delete »
• distribué
– les classes où les objets invoqués peuvent l’être à travers le réseau
– les fichiers peuvent être locaux ou déportés
– flots à travers le réseau
Java est un langage (2/4)
• interprété
– code source
machine)
compilateur
byte-code
– byte code
interprète
Java
exécution du programme
(indépendant de la
run-times
• architecture neutre
Java Virtual Machine
– il suffit d'une machine virtuelle Java
– grâce à l’Abstract Windowing Toolkit (toujours la même apparence),
puis à Swing
• portable
– architecture neutre
– spécification complète du langage (comportement arithmétique,
implémentation des types, …)
Java est un langage (3/4)
• robuste
– plus simple que C++, très typé
– gestion très différente de la mémoire (pointeurs, libération)
– nombreux contrôles de débordement, utilisation systématique des
exceptions dans les bibliothèques d'outils
• sécurisé
– un grand nombre de sécurités intégrées dans le langage (en
particulier au niveau des applets et de la gestion mémoire)
– 3 niveaux de sécurité
• Verifier : vérifie le byte code. (Chaque fichier ".class" possède une marque
calculée, permettant d'interdire les modifications triviales : insertion de virus
par simple ajout par exemple)
• Class Loader : responsable du chargement des classes.
• Security Manager : accès aux ressources
Java est un langage (4/4)
• « hautes » performances
– en fonctionnalités, mais pas en vitesse d’exécution
– les performances sont restaurées par la compilation "Just In Time",
qui permet à la machine virtuelle de mémoriser, puis ré exécuter le
code natif correspondant à une portion de boucle
• « multithreaded » (éventuellement sur une machine mono-processeur)
• dynamique
– adapté à un environnement évolutif
– interprété
• lié aux design patterns par essence:
– itérateurs, objets fonction, inversion de contrôle etc...
Java en 3 acronymes
• La Java Virtual Machine (JVM)
– interpréteurs (java, javaw)
• Le Java Development Kit (JDK)
–
–
–
–
–
compilateur
visualisateur d’applets
générateur de documentation Java
déboggeur
générateur de méthodes C
(javac)
(appletviewer)
(javadoc)
(jdb)
(javah)
• génère les .h, la définition des classes sous forme de structures, les entêtes
des méthodes)
– déassembleur de classes Java
– ...
(javap)
• Les Application Programming Interfaces (API)
– le cœur de Java …
– lire la doc. !
Un exemple
• Un premier programme Java
public class HelloWorld
{
public static void main (String [] args)
{
System.out.println ("bonjour à tous") ;
}
}
• compilation et interprétation
serveur:~/essai_J> javac HelloWorld.java
serveur:~/essai_J> java HelloWorld
boujour à tous
serveur:~/essai_J>
Quelques points faibles
• Les JVM sont par défaut plus lentes que du code natif mais:
– compilation "just in time": une boucle déroulée 10000 fois n'est
interprétée qu'une seule fois
• Java est gourmand en mémoire mais
– les options de lancement "java -X..." permettent de contrôler les
tailles des différentes piles et tas :
– java -Xmx32m -Xms16m -Xss16m
– depuis la V5, on peut donner des directives au gestionnaire de
mémoire
• Certaines constructions du langage sont limitées
– pas de surcharge d'opérateurs
– MAIS : des compilateurs évolués pallient certains manques (on peut
en les utilisant perdre la portabilité)
De C++ à Java en quelques différences
• Pas de structures ni d’unions
• Pas d'alias de types (typedef)
• Pas de préprocesseur (mais on peut l'utiliser)
• Pas de variables ni de fonctions en dehors des classes
• Pas d'héritage multiple de classes
• Pas de surcharge d’opérateurs
• Pas de passage par copie pour les objets
• Pas de pointeurs, seulement des références
• Pas d'appel de "delete"
De C++ à Java en quelques différences
•
•
•
•
Les varargs sont mieux faits
Les templates s'appellent generics, et sont différents
Java propose une syntaxe avancée pour la boucle for
Java permet la conversion automatique des types de base
vers des objets (wrapping ou boxing/unboxing)
• Les enums sont typés
• Java permet d'attacher au code des annotations
• Voir en particulier
http://java.sun.com/j2se/1.5.0/docs/relnotes/features.html
• Java a beaucoup évolué depuis la version 5 (Tiger)
Les bases de Java
Bases de Java : code
• Java supporte un code source écrit en Unicode
– Code sur 16 bits (7 ou 8 bits pour nos codes usuels)
• un caractère Java est sur 16 bits
– Permet
• tous les caractères altérés
• les langages comme
– chinois
– japonais
– …
– Les 256 premiers caractères sont nos caractères habituels
– Codes utilisables partout dans le programme
Bases de Java : organisation
• Hiérarchie imposée
Le paquetage (package)
Il existe un paquetage
sans nom par défaut
Les classes
Les champs (membres C++)
Les méthodes (fonctions membres C++)
• Conséquence :
– chaque désignation complète est de la forme :
package.class.designation
Bases de Java : organisation
Organisation pratique en fichiers (1/2)
• un package= un dossier
• pas de séparation entre la définition et l’implémentation
d’une classe: on oublie les .h...
• une classe publique (MaClasse) par fichier (MaClasse.java)
• Le compilateur crée au moins un fichier objet
(MaClasse.class) par fichier source
• Un programme Java exécutable comprend au moins une
classe ayant une méthode déclarée :
public static void main(String argv[])
• public : pour pouvoir être utilisée partout
• static : méthode de classe, non liée à un objet
Bases de Java : organisation
Organisation pratique en fichiers (2/2)
• import permet de rendre disponible une classe ou un
paquetage pour simplifier les désignations
import monpaquetage ;
// je peux maintenant utiliser directement maclasse au lieu de monpaquetage.maclasse
maclasse objet1 ;
monpaquetage.maclasse objet2 ;
• remarques :
1) Plusieurs syntaxes
2) Possibilité d’importer à travers le réseau
• Variable d’environnement CLASSPATH
• Argument -classpath de l’interpréteur
– pour préciser les chemins d’accès
– toute ressource utilisée par un programme doit être accessible via le
"classpath"
Eléments du langage
• Commentaires: comme C, plus javadoc
/**
ceci est un commentaire très particulier qui sera utilisé par javadoc du JDK
pour générer automatiquement la doc (à lire !) en ligne
*/
x = y ; // ceci est un commentaire qui va jusqu’a la fin de la ligne
// c’est aussi un commentaire
/* cela marche aussi
mais pas de mélange SVP
*/
syntaxe habituelle pour les commentaires plus
/** …
*/
Types
• Les types sont :
– Des types de base prédéfinis (boolean, char, byte, short, int, long,
float, double)
– Des versions "wrappées" (par des classes) de ces types de base
(BigDecimal, BigInteger, Byte, Double, Float, Integer, Long, Short)
– Les classes déclarées par le programme
• Transtypage
– il peut être
• implicite
• explicite (syntaxe du C)
– Il est requis pour les spécialisations explicites, comme en C++
int i = 1 ;
double x = 6.28 ;
x = (float) i ;
Eléments du langage
• Les constantes
– tout identificateur d’une classe déclaré final est une constante
static final int c1 = 12 ;
public final float c2 = 1.2 ;
• Création d’un objet
MaClasse mon_objet ;
mon_objet = new MaClasse () ;
// ne fait que déclarer une référence
// par défaut initialisée à null
// mon_objet fait effectivement référence à un objet
MaClasse mon_objetbis = new MaClasse () ;
//
le constructeur de MaClasse peut ne pas avoir de paramètres
mon_objetbis = mon_objet ;
// référence à un même objet mais pas copie de l’objet
//
Pour réaliser une copie : utiliser la méthode clone de tout objet
mon_objetbis = mon_objet.clone () ;
Eléments du langage
• Les opérateurs = et == appliqués à deux variables
s’appliquent à des références et non aux objets référencés !
– pour = (copie)
définir)
utiliser la méthode clone () (prédéfinie ou à
– pour == (comparaison)
ou à définir)
utiliser la méthode equals () (prédéfinie
• Les chaînes de caractères
– des chaînes constantes : classe String
– des chaînes modifiables : classe StringBuffer
– lire la doc. !
Eléments du langage
• Les tableaux
–
–
–
–
suite d’objets de même type
les éléments sont d’un type prédéfini ou des références sur des objets
doivent être déclarés, créés, voire initialisés
sont des références
//
déclaration
int[] array_of_int;
Color rgb_cube[][][];
// équivalent à : int array_of_int[];
//
création et initialisation
array_of_int = new int [42] ;
rgb_cube = new Color [256] [256] [256] ;
//
utilisation
int longueur = array_of_int.length;
int e = array_of_int[50];
// longueur = 42
// en dehors du tableau : lève une exception
Initialisation de tableaux
• Java permet de construire un tableau lors de sa déclaration
ou de son allocation, en fournissant une liste d'initialisation
• Java connaît la longueur des tableaux, et celle ci est calculée
automatiquement
int[] dims={2,3,4};
String [] noms = {"toto","tata","tutu"};
A [] tabA={newA(1), new A(2)};
int i = dims.length; // la longueur du tableau
Eléments du langage
Structures de contrôle
• Comme en C++ : for , while ...
• Plus génial!: break et continue désignés
boucle1 :
while (...)
{
boucle2 :
for (...)
{
boucle3 :
while (...)
{
if (...) continue boucle1 ;// reprend sur la première boucle while
if (...) break boucle2 ;
// quitte la boucle for
continue ;
// reprend sur la deuxième boucle while
…
// instructions jamais atteintes
}
}
}
Eléments du langage
• varargs et la boucle "for" : énumération implicite d'une
collection
• write("line 1");
• write("line 2", "line 3");
• write("line 4", "line 5", "line 6", "line 7", "line 8", "line
9", "line 10");
public void write(String... records) {
for (String record: records)
System.out.println(record);
}
Eléments du langage : Gestion mémoire
• Allocation
– new: retourne une "strong reference"
• Libération
– la libération de la mémoire est automatique et est gérée par un processus
appelé garbage collector (= ramasseur de déchets ) qui détecte les objets
sans référence
– ce processus fonctionne en tâche de fond de faible priorité, dans un
thread parallèle, mais peut être déclenché explicitement (méthode
System.gc () )
– ne peut libérer que la mémoire allouée par Java
– ne peut pas tout libérer malgré tout
Gestion de la mémoire
• Plusieurs types de références, en plus de la référence
"strong"
– weakReference (n'empêche pas le gc s'il n'y a plus de strong ref)
– softReference (comme weak, mais l'objet dure tant que la mémoire le
permet)
• utile pour mettre en œuvre des caches
– phantomReference (permet de savoir quand un objet a été détruit).
C'est une alternative saine à la redéfinition de "finalize"
Weak References
• Illustration du problème des références. Cette structure de
données associe une information à un Socket, au caractère
volatile.
• Que se passe t'il quand un socket disparaît?
•
(d'après http://www-128.ibm.com/developerworks/java/library/j-jtp11225/)
La fuite de mémoire en action
•
(d'après http://www-128.ibm.com/developerworks/java/library/j-jtp11225/)
Comportement du GC et utilisation de mémoire
•
(d'après http://www-128.ibm.com/developerworks/java/library/j-jtp11225/)
• Solution: utiliser WeakHashMap à la place de HashMap:
intuition du code
•
(d'après http://www-128.ibm.com/developerworks/java/library/j-jtp11225/)
Mots clés significativement différents de C++
consulter : http://www.cs.umb.edu/java/keywords
•
•
•
•
•
•
•
•
•
•
•
•
•
abstract
méthode sans implantation/ classe en contenant
byte
char signé
default
utilisé comme échappement dans un switch
finally
utilisé comme échappement dans un try
final
pour une classe : pas d'héritage possible
final
méthode : pas de redéfinition possible
final
champ : traité comme une constante
instanceof test d'appartenance à classe
native
déclare une méthode implantée en C/C++
null
la référence vide
super
la superclasse
synchronized empêche l'accès simultané à un objet
volatile
déclare un champ partagé et évite des optimisations
abusives (suppression d'une variable par le compilateur, qui ne voit pas
qu' elle est utilisée)
Les concepts des langages
de classes ;
implémentation en Java
Les classes
• La classe est l’élément de base de Java. Tout est classe sauf
les types primitifs (int, float, double, ...) et les tableaux
• Il n’y a pas de fonctions, seulement des méthodes
• Toutes les classes dérivent d'une superclasse commune
java.lang.Object
• L'objet support des méthodes est appelé : this
– this est une référence sur l’objet manipulé
this.champ
Déclaration d'une classe et de ses constructeurs
class Point [extends Object]{
private float x=(float) 0.0;
private float y=(float) 0.0;
public Point(float x, float y){
this.x=x;
this.y=y;
}
public Point(){
this((float)5.0, (float)2.3);
}
}
La classe Object
•
Object() Constructor
•
protected Object clone()
–
•
boolean equals(Object obj)
–
•
réveille tous les threads en attente pour cet objet.
String toString()
–
•
réveille un thread bloqué sur cet objet.
void notifyAll()
–
•
renvoie la clé de hash code associée à l'objet
void notify()
–
•
renvoie la classe d'un objet
int hashCode()
–
•
appelé par le garbage collector avant la récupération de l'esapce occupé par l'objet.
Class getClass()
–
•
permet de comparer deux objets (requis pour les tables de hash code).
protected void finalize()
–
•
crée et retourne une copie de l'objet.
retourne une chaîne de caractère. Utilisée par la jvm pour toutes les conversions en chaînes
void wait()
–
bloque un thread sur cet objet, en attendant qu'un autre appelle notify()
La classe "Class"
public final class Class extends Object implements Serializable
• Les classes sont construites par la JVM automatiquement,
et sur appel de defineClass dans un class loader.
void printClassName(Object boo) {
System.out.println("La classe de " + boo + " est " + boo.getClass().getName());
}
• La formulation suivante s'applique aussi à un type de base
System.out.println("Le nom de classe de Boo est : "+Boo.class.getName());
Méthodes statiques de Class
•
static Class forName(String className)
– renvoie l'objet Class d'un nom donné
– Class t = Class.forName("java.lang.Thread")
•
static Class forName(String name, boolean initialize, ClassLoader loader)
– pareil, mais en utilisant un class loader particulier, avec l'option d'initialiser ou non la
classe désignée
•
La possibilité de charger dynamiquement une classe en Java, est à la base de
possibilités d'utilisation extrêmement flexibles du langage.
•
Par exemple, un programme peut générer le source java d'une classe, invoquer
le compilateur sur ce source, puis charger dynamiquement la classe avec la
fonction "forName" pour enfin en créer des instances et appeler n'importe
laquelle de ses fonctions : par exemple "main" dans Eclipse
•
Ce n'est possible en C++ qu'au prix de grandes difficultés (utilisation d'édition
de liens dynamique (voir "ld")), sachant qu'on ne pourra de toutes façons
appeler sur un objet que des méthodes déjà connues (par exemple des fonctions
virtuelles définies pour une classe compilée statiquement)
Méthodes de Class
•
String getName()
– le nom
•
Package getPackage()
– le package
•
int getModifiers()
– un int contenant des booléens pour public, static etc...
•
Class getSuperclass()
– la superclasse
•
Class[] getInterfaces()
– retourne les interfaces implantées par la classe
•
Class[] getClasses()
– tableau de toutes les classes et interfaces publiques membres de cette classe
•
Class[] getDeclaredClasses()
– tableau de toutes les classes et interfaces membres.
•
Class getDeclaringClass()
– retourne la classe dont on est membre (éventuellement)
Accesseurs de Class
•
boolean isAssignableFrom(Class cls)
– est ce que cls est une sous classe?
•
boolean isInstance(Object obj)
– est ce que obj est une instance de cette classe
•
boolean isInterface()
– interface?.
•
boolean isPrimitive()
– type primitif? (int, void, etc...)
•
boolean isArray()
– un tableau?
•
Class getComponentType()
– le type des composants d'un "array".
Accès aux constructeurs
•
•
•
•
Constructor getConstructor(Class[] parameterTypes)
Constructor[] getConstructors()
Constructor getDeclaredConstructor(Class[] parameterTypes)
Constructor[] getDeclaredConstructors()
– retournent les constructeurs publics, ou déclarés
•
Object newInstance()
– crée une nouvelle instance
Accès aux membres
•
•
•
•
Field getDeclaredField(String name)
Field[] getDeclaredFields()
Field getField(String name)
Field[] getFields()
– retournent les champs de la classe publics ou non
•
•
•
•
Method getDeclaredMethod(String name, Class[] parameterTypes)
Method[] getDeclaredMethods()
Method getMethod(String name, Class[] parameterTypes)
Method[] getMethods()
– retournent les méthodes
Class: fonctions diverses
•
ClassLoader getClassLoader()
– le chargeur de cette classe.
•
ProtectionDomain getProtectionDomain()
– le domaine de protection de cette classe.
•
URL getResource(String name)
– trouve une ressource de nom donné (les ressources sont tous les fichiers de
paramètres, ou de données accessibles dans le classPath).
•
InputStream getResourceAsStream(String name)
– id, mais renvoie directement un flux d'entrée sur cette ressource, prêt à en lire le
contenu.
•
Object[] getSigners()
– renvoie les "signers" de la classe - certificats d'authenticité-.
•
boolean desiredAssertionStatus()
– renvoie le statut par défaut pour assert de la classe (les assertions peuvent être
contrôlées sur une base "classe par classe")
Interfaces
• Une classe ne contenant pas de données peut être déclarée
comme interface
public interface ... { ... }
• Les interfaces n'ayant pas de données, elles servent juste à
définir des interfaces de programmation (d’où leur nom),
souvent encore appelées "protocoles".
• On appelle une interface de programmation un protocole
quand les appels possibles sont régis par un automate (par
exemple, on ne peut appeler "dépile()" sur une pile vide)
Classes abstraites
• Une classe contenant des méthodes abstraites doit être
déclarée abstract
public abstract class ... {
...
public abstract void foo();
}
• C++ ne prévoit pas cette déclaration, toute classe contenant
une méthode définie par zéro (f()=0;) étant abstraite par
nature
• Aucun constructeur d'une classe abstraite ne peut être
appelé explicitement.
Héritage
• Au niveau des classes seul l’héritage simple est possible
class B extends A { …}
• L'héritage multiple des interfaces est possible
class B extends A implements I1, I2 {...}
• Il ne doit pas y avoir de conflit dans les noms de fonctions
apportés par la classe héritée et les différentes interfaces.
Java ne propose aucun mécanisme de désambiguïsation à ce
propos (comme la syntaxe A::f() de C++)
• Toute classe Java (sauf Object) possède exactement une
superclasse (qui est Object par défaut), ce qui permet à Java
d'introduire le mot clé "super" pour désigner cette
superclasse
Les classes : masquage
Masquage de l’information
• Pour les classes
– public : visible de partout
– par défaut : visibilité limitée au paquetage
• Pour les champs et les méthodes, il s’effectue à 3 niveaux
– public: accès illimité
– protected : accès réservé aux sous classes
– private : accès réservé à la classe
– à préciser pour chaque champ et chaque méthode
• Attention, comme en C++, protection au niveau de la classe,
pas de l’objet
Les classes : constructeurs
Les constructeurs (1/2)
• Le constructeur par défaut
• Des constructeurs avec des listes de paramètres différentes
• Un cas particulier intéressant
Class Maclasse
{
public Maclasse ( … première liste de paramètres … )
{…}
public Maclasse ( … deuxième liste de paramètres … )
{…}
public Maclasse ()
{
//
appel d’un autre constructeur. Le constructeur appelé
//
dépend de la concordance des arguments - paramètres
this (une liste de paramètres) ;
}
}
Les classes : constructeurs
Les constructeurs (2/2)
• Constructeurs des classes dérivées
– doit faire appel (explicitement) à un constructeur de la classe de base
Class Maclasse extends Maclassedebase
{
public Maclasse ()
{
super (….) ; // appel avec paramètres
…
}
public Maclasse ( … première liste de paramètres … )
{
super () ;
// si n’existe pas, est rajouté automatiquement
…
}
}
– même hiérarchie d’appels qu’en C++
Les classes : pas de destructeur, mais:
La méthode finalize
• La libération de la mémoire est :
– automatique - donc normalement on ne doit pas la gérer
– désynchronisée
• Le « garbage collector » ne peut toutefois libérer que la mémoire allouée
par Java, et seulement si toutes ses strong references ont disparu
• La méthode finalize est appelée par le GC avant la destruction:
– permet la libération de toutes les autres ressources
– permet la "résurrection de l'objet" en en créant une référence "strong"
• canevas de la forme :
void finalize ()
{
super.finalize () ;
….
}
Les classes : méthodes
• Tous les arguments (types primitifs ou pointeurs) sont
passés par valeur
• Une copie des types primitifs est passée
– une variable d’un type primitif ne peut jamais être modifiée par une
méthode
• Java ne fait jamais de copie d'objets! utiliser "clone()"
• Une copie des références sur les objets est passée
– on peut modifier sans risque le paramètre
– toute modification sur l’objet référencé s’effectue sur l’unique objet
associé
• Surcharge possible des méthodes
Les classes : méthodes et classes abstraites
• La méthode est déclarée abstract
public abstract int ma_methode ( …)
{
…
}
• La classe doit alors être déclarée abstract
abstract class MaClasse
{
…
public abstract int ma_methode ( …)
{
…
}
}
Les classes : méthodes et classes finales
• Une méthode déclarée final ne peut être redéfinie
public final int ma_methode ( …)
{
…
}
• Une classe déclarée final ne peut être dérivée
final class MaClasse
{
…
public final int ma_methode ( …)
{
…
}
}
« Héritage multiple » : Interfaces
• Une interface est une classe particulière
– abstraite
– n’ayant que des champs static final (des constantes)
• C’est une promesse de services qui reste à implémenter
• Une interface peut dériver de plusieurs interfaces
• Une classe peut être l’implémentation de plusieurs
interfaces et hériter d’une classe
interface A
{…}
interface B
{…}
interface C
{…}
interface D extends A, B
{…}
classe MaClasse extends UneClasse implements C, D
{ …}
Les paquetages
• Un paquetage sert à structurer un ensemble de classes,
d’interfaces, … et de paquetages
– offre une structuration logique des classes
– donc plus de lisibilité
– conditionne la visibilité et le nommage
package cours.monpaquet ;
//
MaClasse fait partie du paquetage cours.monpaquet
class MaClasse
{
…
}
– facilite la recherche effective des classes au chargement
– fige une architecture physique
– l’accès au fichier MaClasse.java est
…/cours/monpaquet/MaClasse.java
Les exceptions en Java
• Une méthode doit spécifier ses exceptions dans son entête
public void ma_methode (….) throws my_exception1, IOException
{…}
• Après un bloc try, avec passage ou non dans un gestionnaire
catch, exécution de la clause finally
…
try
{…}
catch (type exception1 paramètre1)
{…}
…
finally
{
//
on passe nécessairement par ici
...
}
• Les exceptions dérivent de la classe Throwable ou des
classes dérivées Error ou Exception
Lancement d'exception
• Attention en Java, on ne crée pas d'objets locaux.
• Une exception doit toujours être allouée par new
• Une exception est lancée avec "throw"
void foo() throws MonException {
...
throw new MonException(...);
}
catch (...) ?
• C++ offre une syntaxe élidée (...) permettant de capter toute
exception possible.
– En C++, tout type de base peut être utilisé comme exception (il est
possible de lancer un "in", ou un "char *") ce qui justifie ce
mécanisme.
• En Java, toutes les exceptions dérivent de Exception, et tout
ce qui peut être "lancé" dérive de Throwable (Error +
Exception)
• catch(Exception e){} correspond donc à catch (...)
• Noter que l'on n'est pas supposé écrire catch (Throwable
t){}, car on laisse normalement la machine virtuelle gérer les
erreurs (AssertionError, ou échec de lancement de Thread
par exemple)
Pointeurs de fonctions
• Java ne permet pas de manipuler explicitement de pointeur
de fonction.
• Le seul moyen d'obtenir ces pointeurs se fait via des
méthodes, qui sont toujours virtuelles en Java.
class Demon {
public abstract void execute(/*params*/);
}
class Ailleurs {
Demon undemon;
Ailleurs(Demon d ){undemon=d;}
void executeDemon(){undemon.execute(/*params*/);}
}
Classes anonymes
Le problème de devoir déclarer des classes pour avoir des pointeurs de
fonctions, c'est qu'il faudrait les nommer. Heureusement, Java permet
de déclarer des classes "au vol", anonymes.
abstract class A {
abstract void g();
}
class Z {
void h(A a){ ... a.g(); ...}
}
...
{
Z z=new z();
z.h(new A(){ void g(){ ... }});
}
Classes locales
• Il est possible de déclarer des classes imbriquées, comme en
C++
• Il est également possible de déclarer une classe locale, dans
une fonction. Sa visibilité est alors limitée au corps de la
fonction
Assertions
assert
• Java intègre depuis la 1.4 la prise en compte de assert.
• Pour que les assertions soient testées, il faut exécuter avec
l'otion "-ea", pour "enable assertions".
– java -ea
• assert expression_booléenne [: expression_non_void]
• "assert" provoque une erreur si son expression_booléenne
est fausse, et la trace va tenter d'appeler la méthode
"toString" de la deuxième expression, si elle est présente
assert
• le test d'assertions peut être contrôlé à trois niveaux : global,
package et classe
• public void setDefaultAssertionStatus(boolean enabled);
• public synchronized void setPackageAssertionStatus(String
packageName, boolean enabled);
• public void setClassAssertionStatus(String className,
boolean enabled);
• public void clearAssertionStatus();
• public boolean desiredAssertionStatus();
• class AssertionError
utilisation de "assert"
• L'instruction "assert" permet la spécification contrôlée d'invariants
• Un invariant est une propriété qui doit toujours être vraie en un point
d'exécution du programme
• On ne doit pas utiliser de tests (if ...then...else) pour contrôler les
invariants mais toujours utiliser "assert"
• Cela sépare deux notions distinctes, et améliore la lisibilité des
programmes. "assert" permet que la spécification d'un programme soit
testée à l'exécution.
• Pour compiler les assert conditionnellement comme en C++, il suffirait
d'utiliser une variable globale, en faisant confiance à l'optimiseur :
– static final boolean TestAssertions=false;
– if TestAssertions assert ...;
• C'est normalement inutile
Threads
Les threads
• Petits morceaux de programme « légers » faits pour
fonctionner « en parallèle » en partageant les données du
même processus
– écriture d’un texte
– bande son
– animation d’une image
• Différents états
–
–
–
–
crée
actif
endormi
tué
Etendre Thread
class PrimeThread extends Thread {
long minPrime;
PrimeThread(long minPrime) {
this.minPrime = minPrime;
}
public void run() {
// calcule les nombres premiers supérieurs à minPrime
...
}
}
//////// pour lancer:
PrimeThread p = new PrimeThread(143);
p.start();
Implanter Runnable
class PrimeRun implements Runnable {
long minPrime;
PrimeRun(long minPrime) {
this.minPrime = minPrime;
}
public void run() {
// calcule les nombres premiers supérieurs à minPrime
...
}
}
//////// pour lancer:
PrimeRun p = new PrimeRun(143); new Thread(p).start();
API de thread
static int activeCount()
nombre de threads actifs dans le groupe
static Thread currentThread()
le thread courant
static boolean holdsLock(Object obj)
le thread courant a t'il un lock sur l'objet?
static boolean interrupted()
le thread courant a-t-il été interrompu?.
static void sleep(long millis[, int nanos])
static void yield()
arrête temporairement, et permet aux autres de s'exécuter
static int enumerate(Thread[] tarray)
copie les threads actifs du groupe
void checkAccess()
possibilité de modifier ce thread? (throws SecurityException)
void destroy()
static void dumpStack()
API de thread
ClassLoader getContextClassLoader()
String getName(); void setName(String name)
int getPriority(); void setPriority(int newPriority);
ThreadGroup getThreadGroup();
void interrupt();
boolean isAlive(); boolean isDaemon() ; boolean isInterrupted()
void join([long millis [, int nanos]])
attend la terminaison de ce thread
void run()
void setContextClassLoader(ClassLoader cl)
void setDaemon(boolean on)
void start()
lance le thread. la machine virtuelle java appelle run()
Classes Génériques
Classes Génériques en Java
• http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf
• Un programme sans génériques
• Un programme avec génériques
Déclaration d'interfaces génériques
Sémantique des génériques
• Très différente de C++ qui génère une nouvelle classe pour
chaque spécialisation d'un template
• Ici, le compilateur génère une seule représentation de la
classe générique, une fois pour toutes. L'information de type
explicite ou implicite (passage d'un paramètre de type
connu) lui permet de générer automatiquement les casts.
• Le code Java produit par des génériques reste compatible
avec du code java standard
Sous typage
• Le comportement du compiltauer pour le sous typage peut
paraître contre intuitif:
• List<String> ls = new ArrayList<String>(); //valide
• List<Object> lo = ls; //invalide
• C'est normal si l'on considère cet exemple:
• lo.add(new Object()); // ok
• String s = ls.get(0); // invalide: on a un "Object" à la place
d'une "String"
Le type "Wildcard"
• Comment faire alors pour déclarer une fonction qui
prendrait en paramètre un conteneur de n'importe quoi?
• A l'ancienne:
• Mauvaise idée:
• La solution: utiliser le "Wildcard"
Désigner une sous hiérarchie
• Considérons une méthode devant dessiner une liste de
formes (naivement List<Shape>).
• Le compilateur refusera un appel avec List<Circle>, alors
que c'est raisonnable
• Il faut utiliser:
• public void drawAll(List<? extends Shape> shapes) { ... }
Méthodes Génériques
• On peut également paramétrer des méthodes par un type.
• On utilise ce mécanisme normalement quand il existe une
dépendance
– entre les types d'un ou plusieurs paramètres
– et/ou celui de la valeur de retour.
• Exemple: ranger les éléments d'un tableau dans une
collection:
• Ne compile pas:
• Il faut écrire:
Wildcard OU Générique ?
• En cas d'ambiguité, s'il n'y a pas de dépendance entre types,
on préfère le "Wildcard"
• VS:
Wildcard ET générique?
• Voici la déclaration de la fonction copy des collections.
• Elle copie une liste de T ou de sous types (src) vers une liste
de T (inutile d'en dire plus)
Génériques imbriqués
• Bien sur, on peut utiliser un type générique comme
paramètre d'un autre.
• Exemple: la fonction "drawAll" conserve un historique
dans une liste statique:
Annotations
Annotations
• Les annotations constituent un mécanisme puissant par
lequel un source peut se voir attacher des informations
exploitées par le compilateur
• ou par des outils annexes capables de générer du code
auxiliaire.
• L'intérêt est de permettre au développeur de ne maintenir
qu'un seul source.
Types d'annotations
• Les annotations sont typées, en utilisant une variante de
notion d'interface. Exemple de définition:
• public @interface MyAnnotation {
•
String doSomething();
• }
• Exemple d'utilisation:
• MyAnnotation (doSomething="What to do")
• public void mymethod() {
•
....
• }
Trois types d'annotations
• Les annnotations ont trois types, dépendant du nombre de
leurs fonctions membres:
• Marker: pas de donnée – un type seul
• Single Element : une seule fonction membre
• Multi Value : plusieurs fonctions membre
• // Marker
• public @interface MyAnnotation {}
• @MyAnnotation public void mymethod() {....}
Exemple Single Valued
• public @interface MyAnnotation
• {
•
String doSomething();
• }
• Utilisation: pas besoin de nommer le paramètre
• @MyAnnotation ("What to do")
• public void mymethod() {
•
....
• }
Exemple Multi Valued
• public @interface MyAnnotation {
•
String doSomething();
•
int count();
•
String date();
• }
• Utilisation :
• @MyAnnotation (doSomething="What to do", count=1,
•
date="09-09-2005")
• public void mymethod() {
•
....
• }
Restrictions
• Les méthodes déclarées ne doivent pas avoir de paramètres
• Pas de clauses de lancement d'exceptions non plus
• Les types de retour ne peuvent appartenir qu'à la liste
suivante:
•
•
•
•
•
types primitifs (int, float...)
String
Class
enum
ou des tableaux des types ci dessus
Annotations prédéfinies
• Annotations simples:
–
–
–
Override
Deprecated
Suppresswarnings
• Méta annotations
–
–
–
–
Target
Retention
Documented
Inherited
Override
•
•
•
•
•
public class Test {
@Override public String toString() {
return super.toString() + "Override";
}
}
• Si le nom de la fonction (toString) ne corespond pas à une
méthode de la super classe, le comilateur génère une erreur
Deprecated et SuppressWarnings
• Deprecated permet de générer des avertissements lors de la
compilation, si un programme utilise une fonction dépréciée
• SuppressWarnings permet de désactiver les avertissements
du compilateur
Méta annotation « Target »
• Target est une annotation d'annotations qui permet de
spécifier ses emplois possibles.
•
•
•
•
•
•
•
@Target(ElementType.TYPE)—tout élément
@Target(ElementType.FIELD)—donnée membre
@Target(ElementType.METHOD)
@Target(ElementType.PARAMETER)
@Target(ElementType.CONSTRUCTOR)
@Target(ElementType.LOCAL_VARIABLE)
@Target(ElementType.ANNOTATION_TYPE)
– Indique que le type déclaré est une méta annotation.
– Ex:
– @Target(ElementType.ANNOTATION_TYPE)
–
public @interface MetaAnnotationType {
... }
Utilisation des tableaux
• On peut grouper les paramètres des « single »
• @Target({ElementType.FIELD, ElementType.METHOD})
•
public @interface Ok {
•
...
•
}
• Mais on ne peut pas les répéter:
• @Target({ElementType.FIELD, ElementType.FIELD})
•
public @interface Erreur {
•
...
•
}
Exemple de Target
• @Target(ElementType.METHOD)
• public @interface Test {
•
public String do();
• }
• Utilisation correcte:
•
@Test_Target("glop")
•
public void methode1() {...}
• }
• Utilisation incorrecte:
•
@Test_Target("pas glop")
•
String monAttribut;
• }
Retention
• La méta annotation « Retention » indique la durée de vie de
l'annotation: source seul, classe, machine virtuelle
• RetentionPolicy.SOURCE
– ignorées par le compilateur
• RetentionPolicy.CLASS
– ignorées par la machine virtuelle, mais utilisables par un outil qui
accède aux .class
• RetentionPolicy.RUNTIME
– lisibles à l'exécution
Documented
• Cette méta annotation indique que Javadoc doit documenter
l'annotation
• @Retention(RetentionPolicy.RUNTIME)
• public @interface Test_Retention {...}
• @Documented
• public @interface Test_Documented {...}
• public class TestAnnotations {
•
public static void main(String arg[]) { ... }
•
@Test_Retention (...) public void methode1() {...}
•
@Test_Documented(...) public void methode2() {...}
• }
• // @Test_Documented apparaîtra dans la javadoc
Inherited
• Par défaut, les annotations d'une classe ne sont pas héritées
par les sous classes
• La méta annotation « @Inherited » permet de modifier ce
comportement sélectivement
• Ne s 'applique qu'aux annotations attachées aux classes
• L'annotation peut etre surchargée, le mécanisme cherchant à
partir de la classe courante
• Les annotations ne sont pas héritées par les classes qui
implémentent des interfaces
Javadoc
Génération automatique de documentation
Javadoc
• Java permet par un outil appelé Javadoc de générr
automatiquement le manuel de référence d'une bibliothèque
à partir de commentaires normalisés, en « html » a format
suivant:
• Début par « /** »
• Utilisation de « <p> » pour formatter les paragraphes
• Utilisation de « { @link ... } pour désigner un élément de la
documentation
• Utilisation de @param, @return... pour désigner les éléments
visés par la documentation
•
•
•
•
/**
*
*
*/
Exemple
• http://java.sun.com/j2se/javadoc/writingdoccomments/index.html
Résultat
Consignes
• La première phrase devrait être courte et constituer un bref
résumé/présentation de l'ensemble.
• Javadoc la placera dans la table des matières et dans l'index.
• Javadoc s'arrête au premier point. Si la phrase doit en
contenir un, il faut ne pas le fare suivre par un espace:
•
•
•
/**
* This is a simulation of Prof.<!-- --> Knuth's computer.
*/
Tags utilisables
• Les tags Javadoc doivent être fournis dans cet ordre:
•
•
•
•
•
•
•
•
•
@param
(classes, interfaces, méthodes and constructeurs)
@return
(méthodes)
@exception (ou encore @throws)
@author (classes et interfaces, requis)
@version (classes and interfaces, requis)
@see
@since
@serial (or @serialField or @serialData)
@deprecated (pour déclarer une api obsolete)
Conclusions sur Java
• Ce cours est un survol de Java, illustrant les différences
essentielles avec C++
• Java est plus simple que C++
• Découvrir Java sur le WEB
• L’apprentissage du langage
– ne peut être que progressif
– n’a d’intérêt que face à des problèmes précis
Il faut prendre du recul
– se situer le plus possible au niveau conceptuel
– les concepts restent, les langages changent
– refuser les astuces et avoir une logique « multi-langages »
• Ne pas rater la révolution du WEB et du multimédia
Pointeurs
• http://www.javasoft.com : Site officiel Java
– (JDK et documentation, téléchargement)
• http://www.javaworld.com : Info sur Java
• http://www-sor.inria.fr/~dedieu/java/
• Le langage Java, Touraivane, cours ESIL, Dpt GBMA
• Le polycopié de C. Chaouiya, cours ESIL, Dpt GBMA
• La première version de ce support de cours a été produite par Marc
Daniel, ESIL
• Google : http://www.google.fr/search?q=java