Refractoring Java Generics by Inferring Wildcards, In
Practic
Michel Mathieu, Nadarajah Mag-Stellon
2014/2015
Table des mati`eres
1 Introduction 2
2 D´efinition de la variance 3
2.1 Pr´emisse . . . . . . . . . . . . . . . . . . . . ....
Chapitre 1
Introduction
Ce rapport est un r´esum´e de l’article intitul´e ”Refactoring Java Generics by Inferring
Wildcard...
Chapitre 2
D´efinition de la variance
2.1 Pr´emisse
La maintenance, la s´ecurit´e et la fiabilit´e des programmes Java augme...
2.2 Variance 4
List<Integer > e n t i e r s = new ArrayList<Integer >() ;
e n t i e r s . add (1) ;
e n t i e r s . add (2...
2.2 Variance 5
public s t a t i c void copy ( List <? extends Number> source ,
List <? super Number> destiny ) {
f or (Num...
Chapitre 3
Cas concret d’utilisation
Apr`es avoir les principes de la covariance et la contravariance, nous allons voir ma...
7
chaque. Ici, nous pouvons alors changer le type de itr en Iterator <?extendsT >. Nous
obtenons alors :
c l a s s WList<E...
Chapitre 4
Le fonctionnement de l’outil
4.1 La syntaxe de la variance
L’outil de refractoring permet d’inf´erer la varianc...
4.2 L’analyse de l’influence des types 9
C’est de cette mani`ere que l’on peut d´eterminer la variance d’un ´el´ement `a pa...
4.2 L’analyse de l’influence des types 10
m´ethode m du fils est fortement d´ependante de la signature de la m´ethode m du p...
4.2 L’analyse de l’influence des types 11
Figure 4.2 – Mini langage
Avec cette syntaxe, on va pouvoir expliciter la varianc...
4.2 L’analyse de l’influence des types 12
Explicitons ces fonctions.
nodesAffectingType(e) permet de retrouver l’ensemble d...
4.2 L’analyse de l’influence des types 13
Figure 4.4 – Pseudo code de l’algorithme du graphe d’influence
Chapitre 5
Les Applications de l’outil
Apr`es avoir vu comment fonctionnait l’outil, nous pouvons voir que plus le nombre ...
15
Figure 5.1 – Statistiques des r´e´ecritures de toutes les d´eclarations pour les types
g´en´eriques
Prenons ici l’exemp...
16
Figure 5.2 – Statistiques des r´e´ecritures de toutes les d´eclarations pour les types variant
Pour les types variant, ...
Chapitre 6
Conclusion
En conclusion, apr`es avoir vu quelques exemples d’utilisations ainsi que son fonctionne-
ment, nous...
Prochain SlideShare
Chargement dans…5
×

Refractoring java generics by inferring wildcards

343 vues

Publié le

Refractoring java generics by inferring wildcards

Publié dans : Logiciels
  • Soyez le premier à commenter

  • Soyez le premier à aimer ceci

Refractoring java generics by inferring wildcards

  1. 1. Refractoring Java Generics by Inferring Wildcards, In Practic Michel Mathieu, Nadarajah Mag-Stellon 2014/2015
  2. 2. Table des mati`eres 1 Introduction 2 2 D´efinition de la variance 3 2.1 Pr´emisse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 2.2 Variance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 2.2.1 La covariance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 2.2.2 La contravariance . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 3 Cas concret d’utilisation 6 4 Le fonctionnement de l’outil 8 4.1 La syntaxe de la variance . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 4.2 L’analyse de l’influence des types . . . . . . . . . . . . . . . . . . . . . . . 9 4.2.1 Le principe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 4.2.2 L’algorithme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 5 Les Applications de l’outil 14 6 Conclusion 17
  3. 3. Chapitre 1 Introduction Ce rapport est un r´esum´e de l’article intitul´e ”Refactoring Java Generics by Inferring Wildcards, In Practice” ´ecrit par John Altidor et Yannis Smaragdakis. Cet article traite d’un outil, un algorithme, permettant de renommer et inf´erer des types plus g´en´eriques d’instances de g´en´eriques Java en utilisant des Wildcards. Des statistiques ont montr´e que sur les six principales librairies Java utilisant les g´en´eriques, 34% des d´eclarations valables de signatures de type variant peuvent ˆetre g´en´eralis´ees, c’est `a dire avec des types wildcard plus g´en´eraux. Or, pour une g´en´eralisation, il faut en moyenne mettre `a jour 146 autres d´eclarations. Cela montre qu’il est tr`es fastidieux de le faire `a la main . C’est dans cette perspective que nous allons ´etudier les principes de cet outil et voir quelques exemples o`u celui ci pourrait am´eliorer notre code. Nous ´etudierons dans un second temps sa s´emantique, ainsi que les principes de g´en´eralisations avec ses probl`emes et les solutions apport´ees. Nous analyserons ensuite son algorithme pour enfin terminer par ses applications.
  4. 4. Chapitre 2 D´efinition de la variance 2.1 Pr´emisse La maintenance, la s´ecurit´e et la fiabilit´e des programmes Java augmentent quand les librairies sont r´enomm´ees pour d´efinir des classes g´en´eriques. En effet, les g´en´eriques per- mettent `a l’utilisateur d’indiquer au compilateur le type des ´el´ements dans une collection et donc d’augmenter la s´ecurit´e en ´eliminant les cast douteux. Seulement, les g´en´eriques restreignent le sous typage comme nous le verrons dans un exemple ci-dessous. Le m´ecanisme de variance dans les langages de programmation modernes essaie de r´esoudre le probl`eme en autorisant deux instanciations d’un g´en´erique qui est sous type d’un autre. Le syst`eme de typage java utilise lui, le concept de ”wildcard”. C’est `a dire, lors de l’uti- lisation d’une classe, nous pouvons choisir de sp´ecifier si elle r´ef`ere `a une ”covariante” ”contravariante” ou ”invariante” version de la classe. 2.2 Variance Afin de mieux comprendre les principes de l’outil, il est n´ecessaire de comprendre la notion de variance. Prenons un exemple, en regardant la diff´erence entre les tableaux et les listes Java. Commen¸cons par les tableaux : Number [ ] nombre = new Number [ 3 ] ; nombre [ 0 ] = new Integer (10) ; nombre [ 1 ] = new Double (3.14) ; nombre [ 2 ] = new Byte (0) ; On peut voir ici qu’un tableau peut contenir des ´el´ements de type T et de n’importe quel sous type de celui-ci. Java fait ´egalement ´etat qu’un tableau S[] est un sous type de T[] si S est sous type de T. On peut alors ´ecrire : Integer [ ] e n t i e r s = {1 ,2 ,3 ,4}; Number [ ] nombre = e n t i e r s ; // correct car Integer est sous type de Number En revanche, avec les listes, cela soul`eve des probl`emes :
  5. 5. 2.2 Variance 4 List<Integer > e n t i e r s = new ArrayList<Integer >() ; e n t i e r s . add (1) ; e n t i e r s . add (2) ; List<Number> nombres = e n t i e r s ; // erreur de compilation Il y a un probl`eme avec les types g´en´eriques. Le compilateur nous interdit formellement de faire ¸ca. Tout ceci affecte le pouvoir du polymorphisme en java. La solution est d’utiliser les outils des g´en´eriques java : la covariance et la contravariance. 2.2.1 La covariance Ici, au lieu d’utiliser un type T comme argument de notre type g´en´erique, on utilise une ”wildcard” <?extendsT > : List <? extends Number> maliste = new ArrayList<Integer >() ; List <? extends Number> maliste = new ArrayList<Float >() ; List <? extends Number> maliste = new ArrayList<Double >() ; Avec la covariance, nous pouvons lire des ´el´ements d’une structure, mais rien n’´ecrire dedans. Ainsi, ”Number n = maliste.get(0) ;” est autoris´e. En revanche ”maliste.add(3.14) ;” est refus´e. En effet, le compilateur ne peut d´eterminer le type exact de l’objet dans la structure g´en´erique. Cela peut ˆetre n’importe quoi qui ´etend Number, mais le compilateur ne peut en ˆetre certain. Ainsi, toute tentative de retrouver une valeur g´en´erique est consid´er´ee comme une op´eration non sˆure et est donc rejet´ee imm´ediatement par le compilateur. 2.2.2 La contravariance Ici, on utilise une wildcard diff´erente : <?superT >. La contravariance nous permet de faire l’op´eration oppos´ee. Nous pouvons lire dans une structure mais pas ´ecrire. List<Object> myObjs = new List<Object () ; myObjs . add ( ” Hello ” ) ; myObjs . add ( ”World” ) ; List <? super Number> nombres = myObjs ; nombres . add (10) ; Dans ce cas, nous pouvons bien ajouter un Number dans la liste nombres car Number a pour ancˆetre Object. En revanche, ”Number n = nombres.get(0) ;” produit une erreur de compilation. En effet nous ne sommes pas sˆurs `a 100% d’avoir un Number. Si le compilateur laissait passer cela, nous pourrions avoir `a l’ex´ecution une ClassCastException. En somme, nous utilisons la covariance quand nous voulons seulement lire une valeur g´en´erique dans une structure et la contravariance quand on veut ´ecrire dedans. Un dernier exemple pour illustrer :
  6. 6. 2.2 Variance 5 public s t a t i c void copy ( List <? extends Number> source , List <? super Number> destiny ) { f or (Number number : source ) { destiny . add (number) ; } } List<Integer > myInts = asList (1 ,2 ,3 ,4) ; List<Object> myObjs = new ArrayList<Object >() ; copy ( myInts , myObjs) ; Tous les types g´en´eriques sont ´etiquet´es comme inh´erents `a la covariance, contrava- riance, bivariant ou invariant au type de leurs param`etres. Cette inh´erence peut donc ˆetre employ´ee `a tous les types g´en´eriques. Par exemple, nous pouvons changer de mani`ere raisonnable toutes les occurences de Iterator < T > en Iterator <?extendsT > ou bien Comparator < T > en Comparator <?superT >. Des chercheurs ont alors d´evelopp´e un outil afin d’am´eliorer cette g´en´eralisation. Il poss`ede diff´erentes fonctionnalit´es : 1. Pour aider le programmeur `a utiliser la variance en Java, il permet de r´e´ecrire automatiquement le code en un code avec des wildcards plus g´en´erales. 2. Cependant, tous les types ne peuvent pas ˆetre r´e´ecris, (ex : s’ils sont d´eclar´es dans une tierce autre librairie o`u le code source n’est pas disponible). Ainsi l’utilisateur peut choisir de ne pas r´e´ecrire le code, si garder un type sp´ecifique est pr´ef´erable pour une future mise `a jour. 3. L’outil respecte la s´emantique Java et pr´eserve le comportement du programme.
  7. 7. Chapitre 3 Cas concret d’utilisation Apr`es avoir les principes de la covariance et la contravariance, nous allons voir main- tenant un exemple d’utilisation de l’outil pour renommer des entit´es d’un programme. Prenons le programme suivant : c l a s s WList<E> { private List<E> elems = new LinkedList<E>() ; void add (E elem ) { addAll ( C o l l e c t i o n s . s i n g l e t o n L i s t ( elem ) ) ; } void addAll ( List<E> source ) { addAndLog( source . i t e r a t o r () , t h i s . elems ) ; } s t a t i c <T> void addAndLog( Iterator <T> itr , List<T> dest ) { while ( i t r . hasNext () ) { T elem = i t r . next () ; log ( elem ) ; dest . add ( elem ) ; } } De mani`ere g´en´erale, l’interface List est invariante. c’est `a dire qu’elle autorise la lecture et l’´ecriture d’un ´el´ement. Or dans la m´ethode addAndLog, pour la liste dest rien n’est lu. On ne fait qu’ajouter un ´el´ement avec add. On peut alors se limiter `a une version contravariante de List en faisant un List <?superT > dest. Pour source, la seule m´ethode invoqu´ee est iterator() qui retourne un Iterator < E >. Or Iterator est covariant comme nous l’avons vu pr´ec´edemment. On peut alors de mani`ere sˆure inf´erer le type de source en List <?extendsT >. Cependant, si on ne changeait que le type de source, le programme ne compilerait pas. En effet, la m´ethode addLog attend un Iterator < T > mais on lui fournit maintenant un Iterator <?extendsT > avec source. Une analyse du programme est alors n´ecessaire pour savoir si la g´en´eralisation d’un type entraˆıne le changement de type d’autres d´eclarations. Ce flot d’analyse doit prendre en compte les d´ependances entre
  8. 8. 7 chaque. Ici, nous pouvons alors changer le type de itr en Iterator <?extendsT >. Nous obtenons alors : c l a s s WList<E> { private List<E> elems = new LinkedList<E>() ; void add (E elem ) { addAll ( C o l l e c t i o n s . s i n g l e t o n L i s t ( elem ) ) ; } void addAll ( List <? entends E> source ) { addAndLog( source . i t e r a t o r () , t h i s . elems ) ; } s t a t i c <T> void addAndLog( Iterator <? extends T> itr , List <? super T> dest ) { while ( i t r . hasNext () ) { T elem = i t r . next () ; log ( elem ) ; dest . add ( elem ) ; } } Apr`es avoir vu un exemple de son utilisation, nous allons maintenant ´etudier son fonc- tionnement.
  9. 9. Chapitre 4 Le fonctionnement de l’outil 4.1 La syntaxe de la variance L’outil de refractoring permet d’inf´erer la variance des types rencontr´es dans un pro- gramme. La variance dans le langage Java est implicite. En effet, il n’y pas de syntaxe pour que le programmeur puisse d´efinir la variance d’un type. Contrairement, au langage Scala o`u il est possible de d´efinir la covariance et la contrava- riance par, respectivement, les annotations + et -. En Scala, par d´efaut, un ´el´ement est invariant. L’outil de refractoring va donc se baser sur un ensemble de r`egles et s’inspirer de la syntaxe de Scala pour la d´efinition de la variance. Intuitivement, la variance d’un ´el´ement est contraint par l’utilisation qu’on en fait. Par exemple, le type des param`etres d’une m´ethode est g´en´eralement contravariant et le type de retour d’une m´ethode est g´en´eralement covariant. Ainsi, notons vx la variance de la variable X. Et, essayons de d´eterminer la variance de quelques ´el´ements sur un exemple plutˆot simple : i n t e r f a c e RList<X> { X get ( int i ) ; } i n t e r f a c e WList<Y> { void set ( int i , Y y) ; } i n t e r f a c e IList <Z> { Z setAndGet ( int i , Z z ) ; } Dans l’interface RList, on remarque que la variable X est covariante car elle est le retour de la m´ethode get. On note cela vx = + et se lit X est covariant dans RList. Dans l’interface WList vY = - (contravariant) car Y est un des param`etres de la m´ethode set. Dans l’interface IList vz = o (invariant) car Z est `a la fois covariant et contravariant.
  10. 10. 4.2 L’analyse de l’influence des types 9 C’est de cette mani`ere que l’on peut d´eterminer la variance d’un ´el´ement `a partir d’une d´efinition g´en´erique. Apr`es avoir inf´erer une g´en´eralisation pour un type donn´e T, l’outil de refractoring permet de remplacer le type T par sa g´en´eralisation. En prenant l’exemple ci-dessous, l’outil de refractoring effectue les substitutions suivantes : i n t e r f a c e RList<X> { X get ( int i ) ; } i n t e r f a c e WList<Y> { void set ( int i , <? super Y> y) ; } i n t e r f a c e IList <Z> { Z setAndGet ( int i , Z z ) ; } 4.2 L’analyse de l’influence des types 4.2.1 Le principe Le fait de g´en´eraliser les types d’un programme implique de nombreux compromis. En effet, plusieurs probl`emes apparaissent lors de la g´en´eralisation d’un type : 1. G´en´eraliser une List < String > par une List <? extends String > pose un certain probl`eme. C’est un exemple qui montre qu’en Java, il est impossible de red´efinir La classe String. Il faut donc se poser la question des classes, des m´ethodes ... immuables en Java. 2. La red´efinition de m´ethode est possible uniquement si les param`etres de la m´ethode du fils sont identiques `a celle du p`ere. Ainsi, lorsque l’on g´en´eralise les types des pa- ram`etres d’une m´ethode fils, Java ne consid`ere plus cette m´ethode comme red´efinition de m´ethode de la m´ethode p`ere. Or, on voudrait que ¸ca soit le cas. 3. La g´en´eralisation d’un type peut amener `a g´en´eraliser d’autres ´el´ements qui sont plus ou moins d´ependant de ce type. L’outil de refractoring ne doit pas ajouter d’erreur de compilation et ne doit pas modifier la s´emantique du programme. Ces probl`emes sont r´esolus en r´ealisant un graphe orient´e des influences sur les d´eclarations dans le programme. Ainsi, l’outil de refractoring construit un graphe d’influence ; Pour chaque d´ependance entre les entit´es (variable, signature de m´ethode ...) A et B, il existe une arˆete qui lie les nœuds correspondant aux entit´es A et B dans ce graphe. Par la suite, lorsque l’on g´en´eralise l’entit´e A, on parcourt le graphe d’influence en g´en´eralisant les noeuds connexe au noeud de l’entit´e A. Pour pallier aux soucis 1, l’outil de refractoring d´ecide quels ´el´ements ne peuvent pas ˆetre g´en´eralis´es. Concernant le probl`eme 2, l’outil va consid´erer que la signature des param`etres de la
  11. 11. 4.2 L’analyse de l’influence des types 10 m´ethode m du fils est fortement d´ependante de la signature de la m´ethode m du p`ere. Dans le graphe d’influence, on va donc ajouter une arˆete entre la signature de la m´ethode p`ere et celle du fils. Pour donner une exemple clair au probl`eme 3, si on g´en´eralise le type de retour d’une m´ethode M alors les variables qui sont affect´ees par la valeur du r´esultat de la m´ethode M doivent ˆetre g´en´eralis´es. Il y aura donc un chemin dans le graphe d’influence qui va lier la m´ethode M et les variables affect´ees par la valeur de M. Prenons, un autre exemple, si l’on g´en´eralise les param`etres p1 et p2 d’une m´ethode M. Et si dans le corps de cette m´ethode M, un objet O fait un appel `a la m´ethode O.m(p1, p2). Alors il faudra g´en´eraliser la signature de la m´ethode O.m. Il existe donc un chemin dans le graphe d’influence entre l’objet O et les param`etres p1 et p2. 4.2.2 L’algorithme Les noeuds du graphe d’influence poss`ede la syntaxe abstraite suivante : Figure 4.1 – Syntaxe du graphe d’influence FieldDeclaration est la repr´esentation des variables de classes ou d’objet. V ariableDeclaration correspond `a la d´eclaration de variables locales. ParameterDeclarations correspond aux param`etres des m´ethodes ou des constructeurs. MethodDecl correspond au type de retour d’une m´ethode. On va ´egalement d´efinir un langage pour d´ecrire les programmes Java. Ce langage nous permettra de d´efinir des fonctions qui nous seront utiles pour l’algorithme d’analyse de l’in- fluence des types et permet d’abstraire la complexit´e de la repr´esentation d’un programme Java.
  12. 12. 4.2 L’analyse de l’influence des types 11 Figure 4.2 – Mini langage Avec cette syntaxe, on va pouvoir expliciter la variance des types par v ou w. Et, le et T sont respectivement la d´enotation du mot cl´e extends de Java et d’un tableau de T1, T2, ...Tn D´efinissons les r`egles des fonctions nodesAffectingType(e) et destinationNode(e) en utilisant ce langage : Figure 4.3 – Fonctions utilis´es par l’algorithme
  13. 13. 4.2 L’analyse de l’influence des types 12 Explicitons ces fonctions. nodesAffectingType(e) permet de retrouver l’ensemble des d´eclarations accesibles dans e qui peut modifier le type de e. Et, destinationNode(e) donne l’ensemble des d´eclarations d´ependant de e. Ces fonctions seront tr`es utilis´ees dans l’algorithme. Pour chacune de ces fonctions, on a d´efini trois r`egles. Par exemple, la r`egle N-MonoMethod d´eclare que si le retour de la m´ethode m ne d´epend pas de e alors seule la d´eclaration de m peut affecter le type < T > m < e >. Parlons de l’algorithme de cr´eation du graphe d’influence. L’algorithme effectue trois pas- sages sur le programme pour analyser : 1. Les appels de m´ethode : pour chaque appel de m´ethode < T > m < e > , on va retrouver les d´eclarations de e dans le programme. On va ´egalement retrouver les m´ethodes qui prennent exactement e en param`etre. Et, on va rajouter une arˆete entre e et les param`etres des m´ethodes trouv´ees pr´ec´edement. 2. Les expressions : pour chaque expression e , on cherche les d´eclarations D qui sont affect´ees par e. Et, pour chaque d´eclaration N qui est accessible par e et qui peut affecter e, on relie dans le graphe d’influence N et D. 3. Les d´eclarations de m´ethode : pour chaque d´eclaration de m´ethode M, on va trouver les m´ethodes M qui red´efinissent ou sont r´ed´efinies par M. On va ajouter une arˆete dans le graphe entre les param`etres des methodes M et M . L’ensemble de ces r`egles permettent de construire le graphe d’influence d’un programme Java Voici un pseudo code de l’algorithme :
  14. 14. 4.2 L’analyse de l’influence des types 13 Figure 4.4 – Pseudo code de l’algorithme du graphe d’influence
  15. 15. Chapitre 5 Les Applications de l’outil Apr`es avoir vu comment fonctionnait l’outil, nous pouvons voir que plus le nombre de d´eclarations augmente dans le graphe, et plus le nombre de d´eclarations immuables fait de mˆeme. Ainsi, moins de d´eclarations seront r´e´ecrites parce qu’il existera plus d’arˆetes o`u les r´e´ecritures sont interdites dans le graphe. Pour palier ce probl`eme, les chercheurs ont pens´e qu’il fallait que l’analyse du programme ignore les d´eclarations qui ne peuvent ˆetre aff´ect´ees par la g´en´eralisation, c’est `a dire ne pas les mettre dans le graphe. Voyons certains exemples de types que le flot d’analyse ignore : 1. Les types primitifs tels que les int, char, boolean ainsi que les types monomorphiques comme String et Object. Ces types ne peuvent pas ˆetre modifi´es avec des wildcards. 2. Les types param´etriques qui sont sp´ecifi´es bivariant ( ¡ ?¿ ). Ces types ne peuvent pas ˆetre plus g´en´eralis´es qu’ils ne le sont d´ej`a. L’outil permet donc de g´en´eraliser des classes en s´el´ectionnant quelles d´eclarations parmi les variables locales, les arguments ou retour de m´ethodes lesquels sont `a renommer. Des travaux pr´ec´edents ont montr´e que 53% des interfaces et 37% des classes peuvent ˆetre g´en´eralis´ees. Ceci montre alors l’impact que pourrait avoir cet outil si toutes ces d´eclarations ´etaient r´e´ecrites. Il aiderait ´egalement les utilisateurs qui n’ont pas de grandes notions de variance `a am´eliorer les performances de leur code. Afin d’´evaleur le potentiel de cet outils, des statistiques ont permis de calculer combien de d´eclarations de types param´etriques pouvaient ˆetre r´e´ecrites. L’outil `a ´et´e test´e sur six librairies java. Nous n’en montrerons que trois ici :
  16. 16. 15 Figure 5.1 – Statistiques des r´e´ecritures de toutes les d´eclarations pour les types g´en´eriques Prenons ici l’exemple des interfaces java, il existe 170 interfaces avec des types pa- ram´etr´es. Parmi celles l`a, 148 peuvent ˆetre r´e´ecrites. Apr`es le passage de l’outil, 34 ont ´et´e r´e´ecrites, soit 20%. Sur l’ensemble des six librairies test´ees, nous obtenons un total 12% de r´e´ecritures en prenant compte les classes et les interfaces, sur un potentiel de 73%. Cela repr´esente tout de mˆeme 2220 sur 18259 r´e´ecritures.
  17. 17. 16 Figure 5.2 – Statistiques des r´e´ecritures de toutes les d´eclarations pour les types variant Pour les types variant, nous voyons que nous obtenons de bien meilleures performances. Sur l’ensemble des six librairies, on obtient un total de 34% de renommage. De plus, la r´e´ecriture seule de JDK ne prend que deux minutes pour 198 milles lignes de code.
  18. 18. Chapitre 6 Conclusion En conclusion, apr`es avoir vu quelques exemples d’utilisations ainsi que son fonctionne- ment, nous pouvons voir que cet outil complexe nous permet d’am´eliorer les perfermances de notre code en g´en´eralisant le plus possible les types param´etriques `a l’aide de wildcards. Cependant, en regardant les statistiques sur le pourcentage de renommage apr`es le pas- sage de l’outil sur les six principales librairies Java, 34% des g´en´eriques ont pu ˆetre plus sp´ecifiques avec des wildcards plus g´en´eralis´ees. Nous pouvons alors penser que cet outil peut encore ˆetre am´elior´e. Des travaux futurs ont ´et´e evoqu´e dans ce sens.

×