novembre
2011
Il semblerait que la conférence Devoxx nous ait apporté quelques informations concernant les lignes directives de Java 9.
On devrait y retrouver les reified generics et l’unification des primitives.
Reified Generics ?
Comme vous le savez surement, les Generics sont fait de telle manière que le paramétrage est perdu à l’exécution. Ce choix délibéré a permit d’éviter la multiplication du code que l’on peut avoir avec un système de Template et de conserver une compatibilité avec les librairies existante, mais il a également certaines limitations sur certaines actions.
En gros il est impossible d’utiliser T.class ou new T() puisque le type T n’est plus connu à l’exécution (pour plus de détail lire : Les Generics ne sont pas des Templates comme les autres !).
La reification a pour but de ramener cette information à l’exécution, ce qui simplifierait son usage et permettrait également d’améliorer encore les vérifications du typeage.
A voir toutefois quels seront les pistes envisagés pour cela, et les conséquences que cela pourrait avoir sur la compatibilité !
Primitives unifiés ?
L’unification des primitives consiste grosso-modo à se débarrasser des primitives afin de n’utiliser ques les objets wrappers associés. Il y a de forte chance que les types primitifs tels que nous les connaissont ne deviennent que des alias pour le type wrapper correspondant.
Qu’est-ce que cela apporterait ? Une plus grande souplesse puisque les primitifs ne devront plus être traités spécifiquement, et qu’on aurait réellement du tout-objet : plus besoin non plus de surcharger ses méthodes pour traiter tous les types primitifs ! Et du coup plus de soucis avec les Generics non plus !!
On pourrait craindre des performances moindre, mais il existe désormais plusieurs techniques permettant cela sans problème… quitte à ce que la JVM utilise toujours les primitives en interne !
7 Commentaires + Ajouter un commentaire
Tutoriels
Discussions
- L'apparition du mot-clé const est-il prévu dans une version à venir du JDK?
- [REFLEXION] Connaitre toutes les classes qui implémentent une interface
- [ fuite ] memoire
- Possibilité d'accéder au type générique en runtime
- Définition exacte de @Override
- Difference de performances Unix/Windows d'un programme?
- jre 1.5, tomcat 6.0 et multi processeurs
- Classes, méthodes private
- Recuperation du nom des parametres
Ca voudrait aussi dire que tu ne pourras plus utiliser les « raw-type » seul, c’est à dire sans le paramétrage Generics. Certe c’est fortement déconseillé, mais il y a encore quelques API Java 1.4 (ou inférieur) qui poserait problème
Ensuite tu as toutes les « unchecked warnings » qui deviendront des erreurs (à la compilation ou à l’exécution). Donc ca risque de casser un grand nombre de code existant, y compris dans l’API standard.
Exemple Collections.emptyList() qui est définie comme ceci :
Bref il y a de forte chance que cela implique des incompatibilités
a++
La question que je me posais était : « Est-ce que ça poserait des problèmes d’incompatibilité ailleurs qu’avec l’opérateur instanceof et les méthodes d’introspection? » (c’est les seuls cas qui me viennent à l’esprit).
Si n’y a pas d’autre cas qui posent problème, on pourrait faire en sorte que ces outils ignorent les paramètres génériques, et introduire des équivalents qui ne les ignorent pas. On conserverait ainsi la compatibilité.
« … quitte à ce que la JVM utilise toujours les primitives en interne ! »
C’est une bonne nouvelle même si ce n’est pas encore pour demain. Et d’ailleurs certains langages tournant sur la JVM (Scala à ma connaissance et d’autres sûrement) le font déjà.
C’est le compilateur qui fait le choix du type réel à utiliser en interne.
Pour les reifieds generics ca dépend de l’implémentation.
Il doit être possible d’intégrer le paramétrage dans chaque instance de manière implicite (que new ArrayList<String>() deviennent new ArrayList<String>(String.class)) afin de pouvoir le récupérer et donc gérer les quelques cas non-géré par les Generics (new T(), T[]). Avec cela il devrait être possible de conserver la compatibilité avec les classes actuelles…
Mais ce n’est toujours pas une « vrai » réification puisqu’on utilise toujours le raw-type.
S’ils s’orientent plus vers un système de Template, chaque instance paramétré aura son propre bytecode qui utilise directement le type paramétré, sans passer par le raw-type. Mais là cela provoque plusieurs incompatibilité puisque les types seront différents…
Bref il y a plusieurs alternatives et j’ignore dans quel sens ils vont s’orienter…
Concernant les primitives ils ne disparaissent pas complètement, mais ils serait simplement « invisible » et stockés dans une référence (plus d’autoboxing donc). Je ne saurais pas vraiment présenté cela mais il existe plusieurs solutions pour cela, de manière transparentes au niveau des sources…
a++
Par contre on avait déjà discuté des primitives dans le sujet sur un #bijava, je ne vois juste pas comment faire cela sans introduire de grosses incompatibilités ou des comportements très trompeurs.
J’ai lu quelques articles qui parlaient d’introduire la réification, mais cela introduisait soit de l’incompatibilité avec l’existant, soit un mécanisme séparé des génériques actuels jusque dans la déclaration.
Je me pose la question : n’est il pas tout simplement possible de rendre l’information des génériques systématiquement disponible au « Runtime » mais ignorées par les « instanceof » et les méthode d’introspection classique. Il suffirait d’ajouter un opérateur « instanceof » reifié et quelque méthodes spécifiques pour l’introspection.
Il me semble cela permettrait de conserver quasiment tous les mécanismes actuel et garantirait la compatibilité, à moins que j’ai oublié quelque-chose d’important.
Et toujours pas de properties? ça serait si simple à ajouter pourtant