F. Barthélemy. 17 mai 2005



Documents pareils
Java 1.5 : principales nouveautés

LMI 2. Programmation Orientée Objet POO - Cours 9. Said Jabbour. jabbour@cril.univ-artois.fr

Chapitre VI- La validation de la composition.

Programmer en JAVA. par Tama

P r ob lé m a t iq u e d e la g é n é r icit é. Pr in cip e d e la g é n é r icit é e n Ja v a ( 1 /3 )

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère

Héritage presque multiple en Java (1/2)

Auto-évaluation Programmation en Java

Traduction des Langages : Le Compilateur Micro Java

Généricité. en Java. (polymorphisme paramétrique) Philippe GENOUD UJF Janvier

RAPPELS SUR LES METHODES HERITEES DE LA CLASSE RACINE Object ET LEUR SPECIALISATION (i.e. REDEFINITION)

Cours 1 : La compilation

Encapsulation. L'encapsulation consiste à rendre les membres d'un objet plus ou moins visibles pour les autres objets.

Premiers Pas en Programmation Objet : les Classes et les Objets

Java Licence Professionnelle CISII,

Génie Logiciel avec Ada. 4 février 2013

Programmation Objet Java Correction

Exceptions. 1 Entrées/sorties. Objectif. Manipuler les exceptions ;

Expression des contraintes. OCL : Object C o n t r a i n t L a n g u a g e

JADE : Java Agent DEvelopment framework. Laboratoire IBISC & Départ. GEII Université & IUT d Evry nadia.abchiche@ibisc.univ-evry.

Lambda! Rémi Forax Univ Paris-Est Marne-la-Vallée

TP1 : Initiation à Java et Eclipse

Polymorphisme, la classe Object, les package et la visibilité en Java... 1

Une introduction à Java

Corrigés des premiers exercices sur les classes

La JVM. La machine virtuelle Java. La JVM. La JVM

Tp 1 correction. Structures de données (IF2)

INITIATION AU LANGAGE JAVA

Utilisation d objets : String et ArrayList

Remote Method Invocation en Java (RMI)

Généralités sur le Langage Java et éléments syntaxiques.

Apprendre la Programmation Orientée Objet avec le langage Java (avec exercices pratiques et corrigés)

Facultés Universitaires Notre-Dame de la Paix. Conception et Programmation Orientées- Object

Introduction à Java. Matthieu Herrb CNRS-LAAS. Mars

Remote Method Invocation Les classes implémentant Serializable

RMI. Remote Method Invocation: permet d'invoquer des méthodes d'objets distants.

Chapitre 10. Les interfaces Comparable et Comparator 1

Threads. Threads. USTL routier 1

Structure d un programme et Compilation Notions de classe et d objet Syntaxe

Corrigé des exercices sur les références

Cours 1: Java et les objets

Cours intensif Java. 1er cours: de C à Java. Enrica DUCHI LIAFA, Paris 7. Septembre Enrica.Duchi@liafa.jussieu.fr

Licence Bio Informatique Année Premiers pas. Exercice 1 Hello World parce qu il faut bien commencer par quelque chose...

Utiliser Java sans BlueJ

Initiation à JAVA et à la programmation objet.

TP1. Outils Java Eléments de correction

Page 1 sur 5 TP3. Thèmes du TP : l la classe Object. l Vector<T> l tutorial Interfaces. l Stack<T>

Java Licence Professionnelle CISII,

Débuter avec EXPRESS. Alain Plantec. 1 Schema 2

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

Machines virtuelles fonctionnelles (suite) Compilation ML Java

Langage et Concepts de ProgrammationOrientée-Objet 1 / 40

Programmation Orientée Objet application au langage Java Version Novembre 2007

Programmation par les Objets en Java

PROGRAMMATION PAR OBJETS

1 Définition d une classe en Java

as Architecture des Systèmes d Information

Objets et Programmation. origine des langages orientés-objet

Info0101 Intro. à l'algorithmique et à la programmation. Cours 3. Le langage Java

Classes et Objets en Ocaml.

Remise à niveau d un programme JAVA du domaine public

Présentation. Au programme. Fonctionnement. A l issue de ce module vous devriez...

Java c est quoi? Java pourquoi?

Programmation Par Objets

Programmation Orientée Objet Java

Remote Method Invocation (RMI)

TD/TP PAC - Programmation n 3

2 e édition JAVA 5 et 6. Jérôme Bougeault. TSoft et Groupe Eyrolles, 2003, 2008, ISBN :

Java Licence Professionnelle CISII, Cours 2 : Classes et Objets

RAPPORT DE CONCEPTION UML :

Meta Object Facility. Plan

Un ordonnanceur stupide

Classe Interne, Anonyme & Enumération

Bases Java - Eclipse / Netbeans

Introduction aux Machines Virtuelles avec VMKit

Étude de l interopérabilité de deux langages de programmation basée sur la machine virtuelle de Java

GOL502 Industries de services

Analyse de sécurité de logiciels système par typage statique

TD3: tableaux avancées, première classe et chaînes

Cours Java Native Interface

Exercices sur les interfaces

OCL - Object Constraint Language

Projet de programmation (IK3) : TP n 1 Correction

Arbres binaires de recherche

Programmation Réseau. Sécurité Java. UFR Informatique jeudi 4 avril 13

Calcul Parallèle. Cours 5 - JAVA RMI

Mémoire de stage de Master 2

Développement Logiciel

Plan du cours. Historique du langage Nouveautés de Java 7

Info0604 Programmation multi-threadée. Cours 5. Programmation multi-threadée en Java

Introduction à la programmation concurrente

Introduction au langage Java

OpenPaaS Le réseau social d'entreprise

Polycopié Cours Programmation Orientée Objet sous Java Programme : Filière SMI S5

INF2015 Développement de logiciels dans un environnement Agile. Examen intra 20 février :30 à 20:30

Java - la plateforme

Institut Supérieure Aux Etudes Technologiques De Nabeul. Département Informatique

Langage et Concepts de Programmation Objet. 1 Attributs et Méthodes d instance ou de classe. Travaux Dirigés no2

Applet pour visualiser les variables «automate» notifiées

Programmation Objet I

Transcription:

Typage de la généricité en Java F. Barthélemy 17 mai 2005 1 Le shéma général La g én éricit é en Java est un ajout r éalis é sur un langage existant depuis d éjà une dizaine d ann ées, avec des contraintes de coçmpatibilit é ascendante. On doit aborder la question à partir de deux grands principes : les règles de typage ne sont pas chang ées, il y a juste de nouveaux types avec de nouvelles règles pour d éfinir la relation de sous-typage. la g én éricit é n existe pas dans le code compil é, au niveau de la JVM. Cela entraîne quelques restrictions dans l usage de la g én éricit é. 1.1 De nouveaux types Voyons un exemple de classe g én érique. Il s agit d une classe Paire qui mod élise une paire de deux él éments du même type. c l a s s P a i r e <T>{ T x, y ; P a i r e ( T x1, T y1 ){ T f i r s t ( ) { return x ; T second ( ) { return y ; void s e t F i r s t ( T x1 ){ void s e t S e c o n d ( T y1 ){ 1

void i n v e r t ( ) { T tmp = x ; x = y ; y = tmp ; boolean e q u a l s ( P a i r e <T> o ){ return o. x. e q u a l s ( x) && o. y. e q u a l s ( y ) ; c l a s s T e s t P a i r e 1 { P a i r e <S t r i n g > p = new P a i r e <S t r i n g >( t o t o, l e é h r o s ) ; On voit dans cet exemple apparaître de nouveaux types par rapport à ceux qu on avait jusqu ici. Rappel des types de Java avant le g én éricit é : types primitifs types tableaux noms de classe noms d interface Ici, nous avons en plus : des variables de type (ex : T, utilis é dans la classe Paire) des classes g én ériques non instanci ées (ex : Paire<T> utilis é dans la classe, pour equals). Les paramètres des classes sont encore des variables. des classes g én ériques instanci ées (ex : Paire<String> utilis é pour les instances de la classe). Les paramètres des classes sont remplac és par des types. Il faut savoir comment ces nouveaux types se raccordent aux anciens d une part, entre eux d autre part, en ce qui concerne l h éritage et la relation de sous-typage. 1.2 Relation de sous-typage Pour m émoire, voici la relation de sous-typage pour les anciens types : Règles fondamentales : Si C est une sous-classe de C, alors C C Si I est une sous-interface de I, alors I I Si une classe C impl émente une interface I, C I Si T T, alors T [] T [] Si T eqt et T T alors T T Règles techniques : nil est le type de null. Si T est un type, alors T T Si T est un type, alors T [] Object 2

Si C est une classe, alors nil C Si T est un type, alors nil T [] Et maintenant voici les règles pour les types param étr és : Si une variable de type T est d éclar ée avec une clause extends C, alors T C (sinon, par d éfaut, T Object) Si une classe C < T 1,..., T n >, est d éclar ée avec une clause extends C < T i..., T j >, alors C < T 1,..., T n > C < T i..., T j > (sinon, par d éfaut C < T 1,..., T n > Object) Note : ici, les T k sont des variables de types. Si une classe C < T 1,..., T n >, est d éclar ée avec une clause extends C < T i..., T j >, alors pour toute substitution θ = [T 1 /C 1,... T n /C n, T i /C i,... T j /C j ] on a C < T 1θ,..., T n θ > C < T i θ..., T j θ > Exemple : c l a s s P a i r e <T>{ T x, y ; P a i r e ( T x1, T y1 ){ T f i r s t ( ) { return x ; T second ( ) { return y ; void s e t F i r s t ( T x1 ){ void s e t S e c o n d ( T y1 ){ void i n v e r t ( ) { T tmp = x ; x = y ; y = tmp ; boolean e q u a l s ( P a i r e <T> o ){ return o. x. e q u a l s ( x) && o. y. e q u a l s ( y ) ; c l a s s T r i p l e t <T> extends P a i r e <T>{ T z ; T r i p l e t ( T x1, T y1, T z1 ){ super ( x1, y1 ) ; 3

z = z1 ; T t h i r d ( ) { return z ; void s e t T h i r d ( T z1 ){ z = z1 ; c l a s s T e s t P a i r e { P a i r e <S t r i n g > t e s t = new P a i r e <S t r i n g >( i c i, l a ) ; System. o u t. p r i n t l n ( t e s t. f i r s t ( ) ) ; System. o u t. p r i n t l n ( t e s t. second ( ) ) ; i f ( t e s t. e q u a l s ( new P a i r e <S t r i n g >( i c i, l a ) ) ) System. o u t. p r i n t l n ( Eagux ) ; T r i p l e t <S t r i n g > r e t e s t = new T r i p l e t <S t r i n g >( un, deux, t r o i s ) ; Voici ce que les règles nous disent, entre autres : P aire < T > Object T riplet < T > P aire < T > P aire < String > Object T riplet < String > P aire < String > T riplet < Integer > P aire < Integer > Cela semble assez naturel. Ce qui l est moins au premier abord, ce sont des relations qui ne sont pas donn ées dans les règles et qui sont donc fausses en Java. P aire < Integer > n est pas un sous-type de P aire < Object > bien que Integer Object P aire < Integer > n est pas un sous-type de P aire < T > (où T est une variable de type) 1.3 Justification des limites du sous-typage La relation de sous-typage permet notamment de d éfinir quelles affectations sont bien typ ées. Si on avait P aire < Integer > P aire < Object >, alors le programme suivant serait bien typ é. Or il n est clairement pas correct. c l a s s PasSousType1 { P a i r e <I n t e g e r > u n e P a i r e = new P a i r e <I n t e g e r > ( 1 2, 4 5 ) ; P a i r e <Object > lameme = u n e P a i r e ; u n e P a i r e. s e t F i r s t ( a r c h i ) ; 4

> javac PasSousType1.java PasSousType1.java:4: incompatible types found : Paire<java.lang.Integer> required: Paire<java.lang.Object> Paire<Object> lameme = unepaire; ˆ 1 error Une relation de sous-typage P aire < Integer > P aire < T > autoriserait le programme suivant, auquel on ne sait pas donner de sens. c l a s s PasSousType2<T> extends P a i r e <T>{ void unemethode ( ) { P a i r e <T> p = new P a i r e <S t r i n g >( a r t y, olm ) ; 1.4 Conséquences des relations de sous-typage Les relations de sous-typage suivantes (d éjà vues) autorisent un certain nombre de choses. T riplet < T > P aire < T > T riplet < String > P aire < String > T riplet < Integer > P aire < Integer > Notamment : l affectation d une instance de la sous-classe dans la super-classe et la cast de la sous-classe vers la super-classe. Exemples : c l a s s Exemple<T>{ P a i r e <T> methode ( T v a l ){ P a i r e <T> u n e P a i r e = new T r i p l e t <T>( val, val, v a l ) ; return u n e P a i r e ; c l a s s T e s t P a i r e 2 { P a i r e <S t r i n g > u n e P a i r e = new T r i p l e t <S t r i n g >( un, deux, t r o i s ) ; u n e P a i r e. e q u a l s ( ( P a i r e <S t r i n g >) new T r i p l e t <S t r i n g >( u, deu, t r o i ) ) ; 5

1.5 Restrictions des constructions dynamiques La machine virtuelle de Java n a pas ét é modifi ée. Une classe param étr ée est compil ée en une classe non param étr ée (nous verrons plus tard comment). Donc les variables de types et les valeurs utilis ées pour les substituer sont oubli ées après la compilation. Certaines constructions qui utilisent les types à l ex écution ne sont donc pas autoris ées avec des types param étr és. Première chose : la cr éation d objet. Un code du genre new T() n est pas permis. Exemple : c l a s s ConstructionDynamique1 <T>{ T x = new T ( ) ; Deuxième chose : un cast vers une sous-classe. Rappel à propos du cast : si T T, alors on peut faire une conversion de type de T vers T, mais cela peut provoquer une erreur à l ex écution. Exemple : c l a s s RappelCast { Compte c = new CompteRemunere ( ) ; CompteSecurise c2 = ( CompteSecurise ) c ; Une v érification de type est faite à l ex écution pour v érifier que le type d instance est un sous-type du type impos é par le cast. > javac RappelCast.java > java RappelCast Exception in thread "main" java.lang.classcastexception: CompteRemunere at RappelCast.main(RappelCast.java:7) Comme les types param étr és n existent pas à l ex écution, on ne peut pas faire de cast vers une sous-classe d un tel type. En revanche, dans l autre sens, de la sous-classe vers la super-classe, le contrôle se fait à la compilation. Il n y a donc pas de problème. c l a s s ConstructionDynamique2 <T>{ T r i p l e t <T> c o n v e r t ( O b j e c t o ){ return ( T r i p l e t <T>) o ; > javac ConstructionDynamique2.java Note: ConstructionDynamique2.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details. 6

> javac -Xlint:unchecked ConstructionDynamique2.java ConstructionDynamique2.java:3: warning: [unchecked] unchecked cast found : java.lang.object required: Triplet<T> return (Triplet<T>) o; ˆ 1 warning Troisième chose : un v érification de type d instance dynamique au moyen de l op érateur instanceof. c l a s s ConstructionDynamique3 { boolean e s t P a i r e I n t e g e r ( O b j e c t o ){ return o i n s t a n c e o f P a i r e <I n t e g e r >; > javac ConstructionDynamique3.java ConstructionDynamique3.java:3: illegal generic type for instanceof return o instanceof Paire<Integer>; ˆ 1 error 1.6 Traduction des classes génériques La g én éricit é a pour seul effet de changer des types pour les variables et m éthodes d une classe. Ces types sont connus une fois la substitution des paramètres effectu ée, c est à dire dans le code qui utilise la classe param étr ée. c l a s s P a i r e <T>{ T x, y ; P a i r e ( T x1, T y1 ){ T f i r s t ( ) { return x ; T second ( ) { return y ; void s e t F i r s t ( T x1 ){ 7

void s e t S e c o n d ( T y1 ){ void i n v e r t ( ) { T tmp = x ; x = y ; y = tmp ; boolean e q u a l s ( P a i r e <T> o ){ return o. x. e q u a l s ( x) && o. y. e q u a l s ( y ) ; c l a s s T e s t P a i r e 3 { P a i r e <S t r i n g > p = new P a i r e <S t r i n g >( t o t o, l e é h r o s ) ; System. o u t. p r i n t l n ( p. x ) ; p. s e t S e c o n d ( a r t u ) ; System. o u t. p r i n t l n ( p. f i r s t ( ) ) ; Se traduit en : c l a s s P a i r e { O b j e c t x, y ; P a i r e ( O b j e c t x1, O b j e c t y1 ){ O b j e c t f i r s t ( ) { return x ; O b j e c t second ( ) { return y ; void s e t F i r s t ( O b j e c t x1 ){ void s e t S e c o n d ( O b j e c t y1 ){ void i n v e r t ( ) { O b j e c t tmp = x ; x = y ; y = tmp ; 8

boolean e q u a l s ( P a i r e o ){ return o. x. e q u a l s ( x) && o. y. e q u a l s ( y ) ; c l a s s T e s t P a i r e 3 { P a i r e p = new P a i r e ( t o t o, l e é h r o s ) ; System. o u t. p r i n t l n ( ( S t r i n g ) p. x ) ; p. s e t S e c o n d ( a r t u ) ; System. o u t. p r i n t l n ( ( S t r i n g ) p. f i r s t ( ) ) ; Dans certains cas li és à l h éritage et à la red éfinition, la traduction est un peu plus complexe et fait intervenir une méthode-pont qui caste les paramètres. En voici un exemple : c l a s s Compte{ i n t s o l d e ; i n t e r f a c e Test <T>{ p u b l i c boolean p r o p r i e t e ( T x ) ; c l a s s DansLeRouge implements Test <Compte>{ p u b l i c boolean p r o p r i e t e ( Compte c ){ return c. s o l d e < 0 ; i n t e r f a c e T e s t { p u b l i c boolean p r o p r i e t e ( O b j e c t x ) ; c l a s s DansLeRouge implements T e s t { p u b l i c boolean p r o p r i e t e ( Compte c ){ return c. s o l d e < 0 ; p u b l i c boolean p r o p r i e t e ( O b j e c t x ){ return t h i s. p r o p r i e t e ( ( Compte ) x ) ; 9