Java : une piste intéressante pour améliorer les types génériques
Un prototype de « generic specialization » en cours de développement

Le , par Amine Horseman

0PARTAGES

1  0 
Même si Java 9 n’est pas encore prêt, une équipe de développeurs est chargée de préparer les nouvelles fonctionnalités de la version 10. Annoncé en juillet dernier, le projet Valhalla, dirigé par Brian Goetz, a pour but d’étudier et tester ces nouvelles fonctionnalités dont la publication est prévue pour 2016.

Il y a quelques jours, Goetz publia un document où il présente l’état d’avancement concernant la gestion des types génériques, l’une des caractéristiques les plus critiquées du Java puisqu’il n’est pas possible, actuellement, d’appliquer des génériques aux types primitifs.

Étant donné qu’Oracle accorde une importance primordiale à la compatibilité avec les versions précédentes, le problème soulevé de par l’introduction d’un tel système de « génériques améliorés » doit être approché avec prudence. En effet, la difficulté est que le « système de types du langage Java n'a pas de racine unifiée », il n'y a pas de type en Java qui est à la fois un super-type d’« Object » et de « int ».

Comme l’explique Goetz, « l'un des premiers compromis avec les génériques en Java est que ces variables ne peuvent être instanciées qu’avec les types de référence, et non pas les types primitifs […] Nous voulons permettre aux classes génériques existantes d’être améliorées, sans avoir à les jeter et les remplacer par de nouvelles. Et en même temps ne pas forcer les programmes existants à être recompilés ou modifiés simplement pour continuer à travailler ».

Pour cela, plusieurs techniques potentielles sont en train d’être étudiées. L’une des pistes les plus prometteuses, appelée « generic specialization », consiste à continuer à représenter les types du genre List<Integer> et List<String> par List.class dans le runtime, tandis que les nouvelles déclarations du genre List<int> seront représentées par un autre type.

L’équipe du projet Valhalla est en train de préparer un prototype pour tester cette technique. Cependant, il est encore tôt pour savoir si elle permet de résoudre efficacement tous les problèmes actuels du typage générique de Java.

Source : Open JDK

Une erreur dans cette actualité ? Signalez-le nous !

Avatar de thelvin
Modérateur https://www.developpez.com
Le 30/12/2014 à 1:52
Hmmm. Bon ça a l'air de marcher. Ça va encore démultiplier les classes à charger en mémoire mais ça on n'y aurait pas coupé à un moment ou à un autre.

Ça va tout de même commencer à devenir compliqué, la lecture des JavaDoc des classes standard Java : "alors les méthodes remove(Object) et remove(int) elles existent que sur les instances où le E de List<E> est un type référence. Pour les types primitifs ça existe pas, utilisez removeItem(E) et removeIndex(int)"
Si ce truc passe je tire mon chapeau à ceux qui arrivent encore à décrocher des certifs Java.
Avatar de super_navide
Nouveau Candidat au Club https://www.developpez.com
Le 31/12/2014 à 9:21
Je comprend pas bien ce genre d'évolution qui n'apporte pas grand chose.

Il ferait mieux de faire en sorte de faire évoluer java pour avoir des performance équivalente a du C++.
La nouvelle fonctionnalité values prévu je sais pas dans quelle version était très intérréssante.
Sinon une fonctionnalité a embarquer dans JDK serait de pouvoir produire un executable qui ne néssécité pas d'avoir un JRE d'installer sur le PC.

Je pense java souffre d'un seul problème ne pas être totalement géré comme python ou C++ pas communauté indépendante.

Mais bon malgré. tous ses défaut je pense que c le meilleur langage car on peut tous faire avec java.

Mais c# arrive pas loin , avec le nouveau framework que microsoft fait qui permet d'écrire une application pour la plupard des plateformes est intéressant.
Mais c# souffre du même problème que java il est la propriété de microsoft.
Avatar de redcurve
Membre confirmé https://www.developpez.com
Le 31/12/2014 à 9:46
C'est vraiment n'importe quoi cette techno
Avatar de ternel
Expert éminent sénior https://www.developpez.com
Le 31/12/2014 à 9:48
Justement, pouvoir avoir des list<int> qui ne passent pas par une conversion vers Integer pourra fortement augmenter les performances de tout programme de calcul.

Quant à "je pense que c'est le meilleur langage parce qu'on peut tout faire", c'est aussi vrai pour tout un tas d'autres langages, comme le C++, le C#, le python, etc.
Le bon outil est celui adapté à la tache.

Personne ne dira "le marteau est le meilleur outil", pourtant, on peut tout faire avec... planter des vis (c'est pas idéal, mais ca marche), cirer des chaussures, démarrer un tracteur, et même coudre un bouton.
Avatar de redcurve
Membre confirmé https://www.developpez.com
Le 31/12/2014 à 9:49
Citation Envoyé par super_navide Voir le message
Je comprend pas bien ce genre d'évolution qui n'apporte pas grand chose.

Il ferait mieux de faire en sorte de faire évoluer java pour avoir des performance équivalente a du C++.
La nouvelle fonctionnalité values prévu je sais pas dans quelle version était très intérréssante.
Sinon une fonctionnalité a embarquer dans JDK serait de pouvoir produire un executable qui ne néssécité pas d'avoir un JRE d'installer sur le PC.

Je pense java souffre d'un seul problème ne pas être totalement géré comme python ou C++ pas communauté indépendante.

Mais bon malgré. tous ses défaut je pense que c le meilleur langage car on peut tous faire avec java.

Mais c# arrive pas loin , avec le nouveau framework que microsoft fait qui permet d'écrire une application pour la plupard des plateformes est intéressant.
Mais c# souffre du même problème que java il est la propriété de microsoft.
C# n'est pas la propriété de MS c'est une spec, pareil pour la CLR et la CLI.

Le .net Framework n'est qu'une implémentation de la CLR/CLI sous Windows.

Toutes les specs sont dispo librement sur le site de l'ECMA
Avatar de gstratege
Membre habitué https://www.developpez.com
Le 31/12/2014 à 10:01
Ça sert à quoi d'avoir des types primitifs ?
Avatar de tomlev
Rédacteur/Modérateur https://www.developpez.com
Le 31/12/2014 à 10:35
Citation Envoyé par super_navide Voir le message
Mais c# souffre du même problème que java il est la propriété de microsoft.
C'est plus tout à fait vrai :
- d'une part, le langage est standardisé par l'ECMA (du moins jusqu'à la version 2 ; je ne sais pas s'ils ont l'intention de faire standardiser les versions suivantes)
- d'autre part, le compilateur est maintenant open-source et cross-platform, et la communauté est fortement impliquée dans sa conception

Certes, c'est toujours Microsoft qui pilote l'évolution du langage, mais je ne vois pas en quoi c'est pire que Java qui est maintenant piloté par Oracle...

Citation Envoyé par gstratege Voir le message
Ça sert à quoi d'avoir des types primitifs ?
Pour des questions de performance, principalement. Les types primitifs correspondent directement à des types de données supportés par le processeur (int, double, etc), qui peuvent donc être traités très efficacement.

En tous cas c'est une très bonne chose qu'ils se penchent enfin sur l'amélioration des génériques; c'est vraiment la feature la plus bancale de Java... Le design actuel partait d'un bon sentiment (garder la compatibilité avec le code déjà compilé existant), mais ça introduit tellement de limitations qu'à mon avis les inconvénients surpassent largement les bénéfices.
Avatar de adiGuba
Expert éminent sénior https://www.developpez.com
Le 31/12/2014 à 12:29
Citation Envoyé par thelvin Voir le message
Hmmm. Bon ça a l'air de marcher. Ça va encore démultiplier les classes à charger en mémoire mais ça on n'y aurait pas coupé à un moment ou à un autre.
C'est atténué par le fait que cela ne concernera que les primitifs/valeurs.
Les Generics avec des références fonctionneront toujours de la même manière.

Citation Envoyé par thelvin Voir le message
Ça va tout de même commencer à devenir compliqué, la lecture des JavaDoc des classes standard Java : "alors les méthodes remove(Object) et remove(int) elles existent que sur les instances où le E de List<E> est un type référence. Pour les types primitifs ça existe pas, utilisez removeItem(E) et removeIndex(int)"
Dans l'idée removeItem(E) et removeIndex(int) seront disponible pour tous les types, et les remove(Object)/remove(int) accessible uniquement pour les références pour la rétrocompatibilité.

Depuis Java 8 la javadoc inclut des onglets pour regrouper les méthodes selon plusieurs critères (instance, static, abstraite, concrète, default...).
On aura peut-être de nouveaux onglets pour gérer cela...

Mieux : c'est absent de ce document, mais dans la version précédente ils parlaient carrément de pouvoir faire une implémentation spécifique pour certains types.
Il serait ainsi possible par exemple d'avoir une implémentation d'ArrayList<boolean> basé sur un BitSet au lieu d'un boolean[]

Citation Envoyé par super_navide Voir le message
Je comprend pas bien ce genre d'évolution qui n'apporte pas grand chose.
C'est un prérequis à l'intégration des types valeurs.
Il serait absurde d’insérer des types valeurs dans le langage si on ne peut pas les utiliser avec les Generics.

Citation Envoyé par super_navide Voir le message
Il ferait mieux de faire en sorte de faire évoluer java pour avoir des performance équivalente a du C++.
Troll ? Ou alors tu es resté bloqué sur la fin des années 90 ?
Un peu de sérieux voyons...

Citation Envoyé par super_navide Voir le message
La nouvelle fonctionnalité values prévu je sais pas dans quelle version était très intérréssante.
Ben c'est le même projet : tout ceci est lié.
Sans specialization l'utilisation des types valeurs risque d'être problématique...

Citation Envoyé par super_navide Voir le message
Sinon une fonctionnalité a embarquer dans JDK serait de pouvoir produire un executable qui ne néssécité pas d'avoir un JRE d'installer sur le PC.
Cela existe déjà (mais pas dans le JDK en effet).
Par contre je n'y vois pas grand intérêt...

Citation Envoyé par super_navide Voir le message
Je pense java souffre d'un seul problème ne pas être totalement géré comme python ou C++ pas communauté indépendante.
Je ne comprend pas trop.
Même si c'est chapeauté par Oracle l'évolution de Java est entre les mains de plusieurs entreprises/organisations...

Citation Envoyé par redcurve Voir le message
C'est vraiment n'importe quoi cette techno
Soit tu argumentes, soit c'est du troll pure et le mieux serait d'aller voir ailleurs.
Ici on préfère les discussions argumentés aux petites phrases toutes faites qui ne veulent rien dire...

Citation Envoyé par gstratege Voir le message
Ça sert à quoi d'avoir des types primitifs ?
Les types primitifs sont des types de base sans notion d'identité. Ils ne représente qu'un espace mémoire réservé à la valeur qu'ils représente.
Les types valeurs sont des types primitifs un peu plus évolué, dans le sens où ils peuvent être composé de plusieurs éléments (un peu comme une structure en C).

Leurs utilités en Java est restreinte, car en les utilisant on "perd" plein de fonctionnalité (pas d'héritage).

Toutefois cela a deux gros intérêts :
  • Une occupation mémoire fixe, qui permet des allocations en bloc pour les tableaux.
    Un tableau de 10 int occupera toujours la même taille en mémoire quelque soit les valeurs stockées, tandis qu'un tableau de 10 Object occupera plus ou moins de mémoire selon les objets qu'on y met.
  • Elle ne comporte que des données, et aucune informations d'identité propre à l'héritage et la POO.
    Cela permet d'être "partagé" plus facilement avec du code natif, ou des instructions bas-niveau, sans avoir à faire des conversions dans tous les sens.


C'est important lorsqu'on fait des traitements 3D ou d'autres choses qui peuvent être manipulé directement par le GPU : on génère les données en Java et on les passe tel-quel pour un traitements optimisés (voir même parallélisés).

Citation Envoyé par tomlev Voir le message
En tous cas c'est une très bonne chose qu'ils se penchent enfin sur l'amélioration des génériques; c'est vraiment la feature la plus bancale de Java... Le design actuel partait d'un bon sentiment (garder la compatibilité avec le code déjà compilé existant), mais ça introduit tellement de limitations qu'à mon avis les inconvénients surpassent largement les bénéfices.
Ils ne vont pas tout changer : les Generics fonctionneront quasiment de la même manière pour les objets.
Ils vont juste introduire une système de template (un peu à la C#), mais uniquement pour les primitives/valeurs.

Sinon perso je ne trouve pas que l'implémentation des Generics soit aussi mauvaise que tout le monde le laisse entendre.
Au contraire je trouve que ses inconvénients sont largement plus décriés qu'ils ne le devraient, et qu'ils y a d'autres avantages qui sont mis sous silence :
  • La compatibilité avec le code déjà compilé comme tu le dis,
  • Mais également l’inter-compatibilité entre du code n'utilisant pas les Generics, et du code les utilisant, au sein d'un même programme sans avoir à faire des conversions.
  • Une covariance/contravariance plus complète, et pas limité à la déclaration du type, et cela dès le début.
  • Une compatibilité avec tous les langages tournant sur une JVM, même si ceux-ci n'ont pas forcément de notion de Generics.


a++
Avatar de oallouch
Futur Membre du Club https://www.developpez.com
Le 31/12/2014 à 15:23
Brian Goetz et son équipe avancent vraiment bien côté langage.
Les lambdas de Java 8 sont une merveille (regardez le source de la classe utilitaire Collectors).
Ils ont pris le temps mais c'est du bon !
Avec ces maj dans Java 9, ils vont résoudre le truc le plus chiant avec les lambdas pour les Collections:
ils vont pouvoir ajouter une méthode stream() à l'interface Iterator...le bonheur !

Maintenant, il faudrait vraiment qu'ils se penchent (je crois qu'ils le font) sur la pauvreté du Hot Swap standard et la nécessité pour tous d'avoir en standard (et gratuit) un truc équivalent à JRebel. Il existe déjà des produits open source (moyennement supportés) comme DCEVM.

Mais, je peux vous dire que quand vous passez de Javascript (quand vous codez votre UI) à Java (pour le serveur), vous respirez !

Olivier Allouch
http://www.illicotravel.com
Avatar de tomlev
Rédacteur/Modérateur https://www.developpez.com
Le 31/12/2014 à 18:31
Citation Envoyé par adiGuba  Voir le message
Ils vont juste introduire une système de template (un peu à la C#), mais uniquement pour les primitives/valeurs.

En C# c'est pas vraiment un système de template (dans le sens des templates C++). Le compilateur produit un seul type générique ouvert, et c'est au runtime que les types fermés sont créés (éventuellement dynamiquement par réflexion). Alors qu'en C++, toutes les instanciations d'un template sont générées directement à la compilation ; ça a certains avantages (performance, plus de souplesse puisqu'on peut faire n'importe quelle opération dans un template du moment que le type utilisé lors de l’instanciation le supporte), mais ça a l'inconvénient d'être complètement statique...

Citation Envoyé par adiGuba  Voir le message
[*] Une covariance/contravariance plus complète, et pas limité à la déclaration du type, et cela dès le début.

Oui mais la variance des génériques en Java n'est pas type-safe... Petit exemple de quelque chose qui va compiler sans problème mais échouer à l'exécution :
Code Java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import java.util.List; 
import java.util.ArrayList; 
  
public class GenericTypeErasure { 
  public static void main(String[] args) { 
    List<Foo> fooList = new ArrayList<Foo>(); 
    List<?> list = fooList; 
    List<Bar> barList = (List<Bar>)list; 
    barList.add(new Bar()); // no error 
    Foo foo = fooList.get(0); // java.lang.ClassCastException: HelloWorld$Bar cannot be cast to HelloWorld$Foo 
  } 
  
  static class Foo { 
  } 
  
  static class Bar { 
  } 
}

En C#, ce serait impossible. Les classes génériques ne sont pas variantes ; seules les interfaces (et les delegates) peuvent l'être, mais il y a des contraintes. Par exemple, l'interface IList n'est pas covariante, parce que T apparait à la fois en sortie et en entrée (un IList ne peut donc pas être affecté à un IList). Par contre, IEnumerable est covariante, car T n'apparait qu'en sortie (un IEnumerable peut être affecté à un IEnumerable)

Après, je reconnais volontiers que l'approche de Java a certains avantages... Il m'arrive occasionnellement de regretter que les wildcards n'existent pas en C#, même s'ils présentent certains risques (comme l'exemple ci-dessus)
Contacter le responsable de la rubrique Accueil

Partenaire : Hébergement Web