septembre
2010
Le langage Java va bientôt fêter ses 15 ans d’existence (sa version initiale datant du 23 janvier 1996). On pourrait même remonter à une vingtaine d’année si on prend en compte sa conception via le Green Project et le langage Oak.
Bien sûr le langage et l’API ont évolués entre temps, tout en respectant au mieux la sacro-sainte règle de la compatibilité ascendante.
Pour rappel il y a deux niveaux de compatibilité ascendante :
- La compatibilité binaire, qui veut qu’un programme compilé avec une version plus ancienne du JDK puisse fonctionner de la même manière sur une JVM plus récente.
- La compatibilité des sources, qui veut qu’un programme compilable avec une version plus ancienne du JDK puisse être compiler sans erreur sur un JDK plus récent, tout en produisant une application qui fonctionne de la même manière.
Tout au long de son évolution, la plateforme Java a toujours fait de son mieux pour respecter ces deux niveaux de compatibilité, même si quelques sacrifices ont pu être consentis, en particulier sur la compatibilités des sources en imposant quelques légères adaptations du code dans certains cas.
Toutefois, ceci n’est pas sans défaut puisque cela implique un grand nombre de limitations. Il est temps de songer à produire une version incompatible, ou tout du moins en partie…
#bijava : Repenser Java
En fait cela fait quelques temps que j’ai ce billet en tête, sans jamais avoir eu le temps d’approfondir la chose. Mais Stephen Colebourne a lancer les discussions sur le sujet, avec une série de billets concernant le prochain « Grand Langage » de la JVM, qu’il nomme « #bijava« , et dont il détaille certains changements incompatibles comme la suppression des types primitifs et des checked-exceptions.
En réalité c’est principalement la compatibilité des sources qui est remis en cause, car cela limite trop l’évolution du langage, ou en tout cas l’utilisation qui en est faite.
Passons au tout-objet : Plus de primitives ni de tableaux
Les primitives sont traités de manière particulière dans le langage, et apportent leurs lots de restriction et de cas particulier :
- Les types primitifs ne peuvent pas être directement stockés dans un tableau d’objet, ainsi que les paramètres varargs, à moins d’utiliser uniquement un tableau de primitifs.
- Les primitifs ne sont pas utilisables avec les Generics.
- Les primitifs ne peuvent pas être utilisés avec la reflection sans passer par une conversion vers les types wrapper.
- Les primitifs ne sont pas des objets, et mettent en places des concepts bien distincts des références.
Il pourrait être intéressant de passer au tout-objet et de se débarrasser de cela.
Les types primitifs pourraient être remplacés par le type wrapper correspondant (quitte à ce que la JVM continue à les utiliser en interne pour des raisons de performance si besoin). A la rigueur par simplicité on pourrait même utiliser les types primitifs comme synonymes des types wrapper (par exemple utiliser int serait strictement équivalent à Integer, sans avoir de mécanisme d’autoboxing à l’exécution).
L’intérêt de tout cela consiste à manipuler uniquement des références sur des objets, en supprimant les cas particuliers. Cela faciliterait l’utilisation des types nullables et l’association de l’opérateur == à la méthode equals().
En finir avec les checked-exceptions
Les checked-exceptions : un des gros concepts de Java, qui promettait un code plus sûr en obligeant les développeurs à traiter les exceptions. Dans le principe l’intention est louable, mais en pratique cela aboutit trop souvent à l’effet inverse : la gestion des exceptions étant tellement lourde qu’on se retrouve à traiter les exceptions uniquement pour rendre le code compilable, et pas forcément pour mettre en place une solution de contournement.
On se retrouve trop souvent avec des traitements inutiles voir dangereux car ils peuvent masquer l’origine exact d’un problème en en générant d’autres par la suite. Il faut en finir avec cela, surtout que cela ne poserait aucun problème d’incompatibilité : cette notion n’existe qu’au niveau du langage via une vérification du compilateur. Lors de l’exécution il n’y a aucune différenciation entre les deux types d’exceptions (d’ailleurs il y a moyen de gruger le compilateur pour remonter silencieusement une checked-exception).
Quid de la compatibilité ?
Les propositions ci-dessus pourraient très bien être effectuées en conservant la compatibilités binaire.
Mais tant qu’à repenser le langage, ne pourrait-on pas aller encore plus loin, quitte à proposer à coté un « mode de compatibilité » pour les anciennes applications. Le JDK8 devrait apporter un concept de modularisation (projet Jigsaw), et il fut un temps question d’un nouveau format d’archive afin de combler les défauts du format JAR.
On pourrait profiter de ces deux concepts pour mettre en place une cassure dans la compatibilité :
- Les applications actuelles seraient exécutées avec des modules garantissant la compatibilité ascendante.
- Les applications futures s’exécuteraient avec des modules incompatibles, profitant des évolutions du langage.
L’idée est simple : modifier grandement la syntaxe et l’API de Java, afin de repartir à zéro sur des bases un peu plus saine. Les programmes et librairies Java actuels seraient exécutés dans un « mode de compatibilité », mais les nouveaux projets pourraient bénéficier de tous les avantages de la nouvelle plateforme Java.
Et si on allait plus loin ?
Nota bene : il ne s’agit ici que d’idée en vrac de ma part, et non pas de proposition officiel ou quoi que ce soit d’autre…
Nettoyer l’API standard
L’API standard est assez énorme, et en toute logique elle n’est pas forcément toujours parfaite. Il est temps de faire un peu le ménage là dedans et de supprimer les classes/méthodes/attributs inutiles…
Non seulement l’API conserve toujours un grand nombre d’élément « deprecated » dont il serait bon de se débarrasser définitivement, mais elle possède également un grand nombre d’éléments devenu inutile, remplacés par une nouvelle API plus propre. Je pense par exemple aux classes Vector/Hashtable (remplacées par l’API de collection et les implémentations de List/Map), à la méthode Runtime.exec() (remplacée par la classe ProcessBuilder), à la classe File (qui sera remplacée par la classe Path et son API bien plus complète dans Java 7).
En toute logique la suppression de ces éléments impliquerait également une fin de la compatibilité binaire.
Mais on pourrait ruser un peu en utilisant une « suppression logique », par exemple en utilisant une annotation @Deleted qui fonctionnerait un peu sur le même principe que @Deprecated, à une différence près : les éléments ainsi marquées ne seraient visible que dans le « mode de compatibilité » avec les anciens binaires.
En clair, une méthode marquée avec l’annotation @Deleted serait toujours visible pour les anciennes applications (de la même manière qu’avec l’annotation @Deprecated). Par contre elle serait totalement inexistante dans les nouvelles applications, que ce soit dans la documentation, à la compilation ou même à l’exécution.
L’intérêt étant de pouvoir faire le ménage en proposant aux futurs développeurs une API clair et net !
Cette annotation pourrait également être associée à une version du JDK et un message d’erreur, par exemple :
@Deleted(version=1.7, message="Use java.nio.file.Path instead")
public class File {
...
En compilant pour une application Java 1.7, la classe n’existe pas et son utilisation affiche le message d’erreur indiqué (afin de faciliter le portable de l’application). Par contre en exécutant un programme plus ancien, la classe serait parfaitement visible afin de garantir la compatibilité.
Revoir complètement les concepts associés au langage
Certains des concepts du monde Java sont un frein à son évolution. Je pense en particulier à la notion de getter/setter qui est utilisée massivement malgré qu’il ne s’agisse que d’une convention de nommage.
Pourtant cela a soulevé de nombreuses discussions quand à l’intégration d’un mécanisme de property au sein du langage. En effet on y distinguait deux grandes écoles :
- Des propositions de property simpliste basées sur du sucre syntaxique, qui se contentait en fait de générer les méthodes getter/setter, mais qui avait l’avantage de rester totalement compatible et en accord avec le concept des getter/setter.
- Des propositions plus poussées qui intégrait un vrai système de property dans le langage, mais qui impliquait de revoir toutes les APIs afin de pouvoir en profiter pleinement.
Si on veut un vrai mécanisme de property en Java, il serait préférable de « casser » le langage.
Supprimer les tableaux (aussi)
Les tableaux posent de nombreux problèmes. Il s’agit d’objets un peu atypique qui nécessitent des traitements particuliers à tous les niveaux. Ils possèdent un système héritage particulier et dangereux (les vérifications de type ne peuvent s’effectuer qu’à l’exécution, donc en générant des exceptions).
On ne devrait pas les utiliser directement. Il serait nettement plus cohérent d’utiliser une classe Array
Intégrer les nouveautés du langage
Dans le même ordre d’esprit, il serait intéressant d’utiliser les nouveautés du langage dans les APIs existantes, et non pas seulement dans les nouvelles APIs.
On trouve ainsi un grand nombre de méthode utilisant un int en paramètre, et dont les valeurs possibles sont définis dans des constantes. Tout ceci pourrait avantageusement être remplacé par des enums, voir par le couple interface/enum.
Il en est de même pour les futures évolutions : les expressions lambda sont convertible en type SAM, ce qui les rend inutilisables avec certains listeners d’AWT/Swing qui définissent plusieurs méthodes…
Plus généralement, les évolutions du langage apportent leurs lots de nouveaux concepts et de nouveaux patterns, qui ne sont pas forcément adaptable aux anciennes APIs sans tout casser. Du coup l’API standard peut sembler assez disparate d’un package à l’autre…
Revoir la gestion de la synchronisation
La gestion de base de la synchronisation est gérée dans la classe Object avec les méthodes de synchronisation wait()/notify(), puisque n’importe quel objet peut servir de lock pour la synchronisation. Personnellement je n’ai jamais compris ce principe !
Sur les 9 méthodes public de la classe Object, 5 concernent les méthodes de synchronisation, que l’on retrouvera donc dans tous les types via l’héritage (puisque tout hérite de Object). D’une part c’est assez troublant pour le débutant, qui est rapidement confronté à ces méthodes sans forcément les comprendre, et d’autre part cela augmente le risque d’erreur en manipulant tout et n’importe quoi comme lock.
Il serait nettement préférable de bien séparer tout cela dans une classe spécifique, et ainsi clarifier l’API et l’utilisation de la synchronisation. Surtout que Java 5.0 a introduit une API de Lock bien plus complète. Je ne vois strictement aucun intérêt au fait de pouvoir utiliser n’importe quelle référence comme moniteur de lock !
En clair, il serait préférable d’utiliser uniquement la classe Lock pour gérer la synchronisation, et non plus n’importe quel objet. Cela permettrait également d’épurer l’API de la classe Object (et donc dans le même temps de toutes les classes).
Distinguer les constantes des attributs
Java met en place un mécanisme de constante un peu particulier : une constante est un attribut déclaré final, assigné en ligne à la déclaration, et dont la valeur peut être déterminée à la compilation. Par exemple :
public static final String HELLO = "Hello World!"; // Constante
public static final String HELLO = System.getProperty("java.vm.name"); // Attribut
Le problème vient du fait que ceci peut être fait de manière involontaire. Or lorsqu’on utilise une constante, le compilateur remplace tous les appels explicites par la valeur de la constante. Du coup le changement de la valeur de la constante n’est reportée aux classes externes qu’après une recompilation, ce qui n’est pas toujours souhaitable.
Il serait souhaitable de forcer les développeurs à définir explicitement leurs constantes, afin de mieux comprendre les mécanismes que cela implique :
public const String HELLO = "Hello World!";
Remettre tout à plat
Il y a surement un grand nombre d’autres modifications incompatibles qui pourrait être apportés au langage et à l’API. D’ailleurs je ne suis pas sûr que les idées de ce billets fassent l’unanimité. L’idée principal à retenir est qu’il serait temps d’engager les discussions sur un éventuelle nouveau langage Java, qui prendrait le temps de voir les concepts mis en place par les autres langages, afin de prendre les meilleures idées ici et là…
Bref commençons à imaginer un nouveau Java, quitte à donner de grands coups de balai !
23 Commentaires + Ajouter un commentaire
Tutoriels
Discussions
- Définition exacte de @Override
- L'apparition du mot-clé const est-il prévu dans une version à venir du JDK?
- [ fuite ] memoire
- Difference de performances Unix/Windows d'un programme?
- jre 1.5, tomcat 6.0 et multi processeurs
- Classes, méthodes private
- Possibilité d'accéder au type générique en runtime
- Recuperation du nom des parametres
- [REFLEXION] Connaitre toutes les classes qui implémentent une interface
Tout à fait d’accord avec toi sur les properties !
Toutes les propositions sur le sujet que j’ai vu passé sur le projet Coin aurait entrainé des changements important qui n’aurait pas pu être utilisé facilement.
Pareil pour le reste… Le seul point qui me gêne avec Scala c’est vraiment sa syntaxe avec laquelle j’ai beaucoup de mal.
A vouloir trop simplifier je trouve que cela nuit à la lecture du code…
a++
je vais regarder les propositions bijava sous l’angle de Scala, histoire de voir… En effet, je suis en train de regarder de plus près ce langage et il me semble très approprié comme remplacement de Java. Cela implique toutefois que je suis encore un débutant en scala, aussi je puis aisément me tromper…
Allons y:
* Nettoyer l’API standard
Scala s’y est sacrément attelé et propose même des outils d’extensions de librairie sans casser la rétro compatibilité. Bref, que du bon.
* Revoir complètement les concepts associés au langage
Ca soulève bien des problèmes en soi en matière d’adoption. Disons que je le prends sous la forme « les nouveautés de Scala ne devraient pas faire peur ».
=> properties. Ouarf bof, encore un mot clé… Je préfère l' »uniform access principle » à la Scala. Pas de mot clé et tout bénef
* Supprimer les tableaux (aussi)
Fait par Scala AMHA.
En fait ils sont même allés bien plus loin avec leur refonte des collections (scala 2.8) et leur insistance sur les collections immutables (rendues possibles par la réutilisation des noeuds n’ayant pas bougé d’une version d’une structure à une autre). Et avec Scala 2.9 arrive le parallélisme pour les collections, qui poussera tout cela encore plus loin. Bref, scala a tout bon là à priori.
* Intégrer les nouveautés du langage
Scala bénéficie d’une part de son age moindre et d’autre part de sa philosophie permettant d’étendre le langage significativement sans ajouter de mot clé ou nouveaux mécanismes relevant du langage lui même. Cela prémunit d’autant de grosses déprécations. Maintenant toujours utiliser les nouveautés dans les librairies systèmes requiert une discpline (et des moyens) dans la durée. Je ne sais pas si l’équipe Scala a tout cela, à priori oui je dirai.
* Revoir la gestion de la synchronisation
Là scala ne propose pas une réécriture de l’API standard Java à plusieurs choses près:
– pas de classe Object avec plein de méthodes discutables spécifiques au multithreading AFAIK => un bon point facile,
– ajout de la notion d’Acteur et donc approche supplémentaire du multithreading. Vu le bien qui est dit des Actor, cela ne semble pas être négligeable,
– bonne interopérabilité avec le code Java: java.util.concurrent et tous ses goodies sont accessibles
* Distinguer les constantes des attributs
Scala le fait de base via le mot clé val (par opposition à l’autre déterminant de variable qui est var, pour justement un élément variable). Bref, du tout bon.
* Remettre tout à plat
Fait, notamment avec l’influence de la programmation fonctionnelle.
J’ajouterai enfin:
– que scala existe là où bijava n’est qu’un voeux pieux
– que la notion de trait scala me semble bien plus prometteuse/efficace que celle de classe et d’interface de Java
Qu’en dites vous?
Pour info on devrait pouvoir utiliser les Exceptions comme type paramétré dans Java 8, via la notion d’Exception Transparency intégré aux Lambda…
Et concernant le bloc finally qui peut cacher une autre exception, Java 7 introduira la notion de « suppressed throwable » pour gérer ce cas là manuellement (ce sera automatique dans le try-with-ressource).
En fait tout ce que je veux, ce serait de pouvoir choisir pour n’importe quelle exception si elle doit être traiter comme une checked-exception ou pas…
a++
Moui…. à part le fait que les EDI font n’importe quoi de cheval (on s’est assez fritté avec l’équipe Netbeans à ce sujet) je suis modérément d’accord.
mais soyons positif et dans l’esprit brainstorming…. quelques idées en vrac.
(dans un brainstroming on a le droit de dire toutes les bétises qui nous passe par la tête hein…)
– clause throws obligatoire pour les exceptions controlées mais sucre syntaxique permettant de balancer l’exception à un système de log par défaut quand on ne veut pas écrire le try/catch (dommage mais pour le moment on ne peut pas faire une annotation sur un bloc de code -ça a été demandé dès le départ-)
– Exceptions comme type paramètre avec tout ce qu’il faut comme accompagnement. pas possible actuellement vu la gestion des catch (mais réalisable avec un système dynamique? à voir)
– déclenchement des exceptions avec détente en suspens…. bon ça ne veut rien dire alors le mieux est de donner un exemple (un peu tordu, lié à la notion de continuation?)
soit un type Prix avec des opérations addition, soustraction , multiplication
la soustraction peut déclencher une exception (si le résultat peut aboutir à une valeur négative qui n’est pas possible avec le type Prix, on peut discuter de la nature de cette exception )
Maintenant on voudrait pour pouvoir réaliser un ensemble d’opérations sur les Prix: ce qui compte c’est que le Prix final soit effectivement correct mais pendant le cours de l’opération il est possible que temporairement la valeur ne le soit pas). comment réaliser ça correctement? avec du Java standard actuel il faut écrire du code assez tortueux…
– savoir si du code est exécuté au cours d’une remontée d’exception: au jour d’aujourd’hui dans un bloc finally exécuté au cours d’une remontée d’excepion on peut déclencher une nouvelle exception qui fait « disparaitre » l’exception en cours de propagation.
– rendre « visible » dans le code les endroits où une exception remonte
(on fait appel à un code qui propage une exception, on la repropage mais, du coup on ne « voit » pas que certains codes ne seront pas exécutés -il y a eu des bugs méchants à cause de ce manque de visibilité dans le code-)
– une meilleure organisation des sous-classes de Throwable + un type d’exception intermédiaire entre runtime et controlée: la non-capture provoque un warning pas un refus de compil. (autre version: quand on balance volontairement une exception controlée on prend quand même un warning)
– épurer le code des librairies standard de java qui font des printstacktrace!
(quelle horreur!)
– …. ? ????
@professeur shadoko : Ce que je regrette surtout, c’est l’impossibilité d’ignorer une checked-exception sans avoir à l’encapsuler dans une autre exception…
Or la plupart des cas il est préférable de laisser remonter silencieusement l’exception plutôt que de la traiter de manière incorrect.
Les checked-exceptions couplé à l’aide des EDIs génère des codes affreux
a++
avec beaucoup de retard (je n’avais pas vu cette discussion) je me joint à ceux qui regrettent le mauvais procès fait aux exceptions controlées (checked exceptions). Je ne suis pas du tout d’accord avec l’article de référence d’Anders Hejlsberg.
Oui il y a des mauvaises utilisations/compréhension des exceptions, oui on pourrait remettre en cause les catégories de Throwable (et en rajouter pour certains besoins) mais jeter le bébé avec l’eau du bain me semble une très très mauvaise idée.
un nouveau langage (dans le cadre de « grandes » applications) doit présenter des progrès pas une régression!
autre sujet: de manière générale un point n’est jamais abordé dans la conception des langages: l’ergonomie du programmeur. quelle est la « lisibilité » du code: tout le monde s’habitue à son langage favori mais je n’ai jamais vu d’étude expérimentale sérieuse sur ce sujet.
L’approche de scala est pas mal pour la gestion mémoire des types simples. Le compilo détermine si il transforme l’objet en type simple ou pas pour raisons de perfs. (bon, pas contre je suis loin de comprendre précisément sur quoi il se base pour le faire )
Le problème c’est que la surcharge d’opérateur peut s’avérer très dangereuse lorsque c’est mal utilisé… Et que son utilité est surtout réelle pour les types numériques (et pourrait donc être intégré au langage).
Sinon, je viens de lire la présentation « One JVM, Multiples Languages » de JavaOne 2010 : http://cr.openjdk.java.net/~jrose/pres/201009-OneVMManyLanguages/
A partir de la page 50 ils parlent de la notion de « Fixnums » déjà utilisé dans d’autres langages comme Lisp ou Smalltalk afin de limiter l’occupation mémoire des objets représentant les types primitifs.
Le principe consiste à marquer les références qui contiendront directement la valeur entière au lieu de l’adresse de l’objet. En clair lorsqu’on manipule un Integer, au lieu d’avoir une référence qui pointe vers un objet en mémoire, on aura une référence qui contient directement la valeur numérique.
Cela pourrait être une bonne option pour la suppression des primitifs.
a++
j’avoue que j’aime bien la surcharge d’opérateur a la scala.
en gros on peut appeler une méthode par * ou – ou +, et défnir donc l’opération associée dans la méthode.
ca permet d’écrire objetA+(objetB)et avec un peu de sucre syntaxique (genre parenthèses optionnelles si un seul argument) : objetA + objetB
c’est peut etre parce que j’ai été obligé de faire pas mal de calculs financiers avec BigDecimal, mais ca me parait indispensable
par contre, effcitement un import class.* ne fonctionne plus, car * peut etre un nom de méthode.
(groovy a le même genre d’approche il me semble)
Dans l’explication de Stephen Colebourne, il parle de changer le comportement de == afin qu’il correspondent à un appel de equals(), en introduisant un nouvel opérateur pour l’identité (=== par exemple).
Note : Je rappelle quand même qu’on parle d’un langage incompatible avec le Java actuel
a++
En effet. Il y a aussi l’opérateur « == » qui s’il n’est pas surchargeable « à la C++ » va poser de sacrés problèmes vu qu’il compare normalement des références et non des valeurs.
Les checked-exceptions sont à double-tranchant. Le minimum serait d’avoir un moyen simple de les remonter silencieusement (et pourquoi pas une annotation en effet) et de les catcher (actuellement le compilateur génère une erreur si on tente de catcher une checked-exception alors qu’elle n’est pas déclarée dans les méthodes du bloc try).
La suppression des primitifs impliquerait en effet une surcharge des opérateurs… mais pas forcément une surcharge libre comme en C++ (ce que je n’approuve pas vraiment). On pourrait largement se contenter d’une surcharge au niveau du langage. Le principal problème que j’y vois vient de l’opérateur + entre Object qui génère déjà une String…
a++
Pour les exceptions, Je ne suis pas contre un allègement localisé de la rigueur des checked exceptions via une annotation @DoNotCheck(exceptions_a_ignorer) par exemple.
Mais je pense que d’avoir des exceptions qui demandent d’être traitées par défaut est un réel avantage.
Pour la suppression des primitifs par contre, je serais intéressé de savoir comment tu penses que Java devrait gérer ça car ça me parait avoir des implications énormes (surcharge des opérateurs, …)
@Uther : Oui la réification des Generics pourrait être un bon client, vu que les deux approches envisagées pour cela risquent de poser des problèmes de compatibilités ou la création d’une nouvelle API…
@joseph_p : un tel saut ferait effectivement peur au monde de l’entreprise…
Mais l’idée consiste justement à simplifier le langage, en se permettant d’y incorporer des fonctionnalités sans contrainte. Ce qui à terme serait bénéfique.
Le langage qui est sortirait ne serait pas forcément Java, même s’il en conserverait la même syntaxe de base à la C…
@lunatix : Le lien est déjà dans le billet
a++
sur le même theme : http://www.jroller.com/scolebourne/entry/the_next_big_jvm_language1
groovy est certes tres sympa, mais les langages dynamiques sont a mon avis mal adaptés aux entreprises. le coté type safe de java (entre autre) permet d’avoir une compilation qui securise grandement le developpement.
Scala a de tres bon cotés (pas de type primitif, les traits etc…) mais par moment, ca ressemble a du Perl. A mon sens ils ont été trop loins.
clojure : je ne crois pas qu’un lange purement fonctionnel puisse devenir le langage principale de la JVM. le changement de paradigme est trop dur.
peut etre faudrait-il chercher du coté de phantom.
Je pense qu’un tel saut ferait peur à bien du monde dans le monde de l’entreprise. Une telle rupture implique un effort de formation considérable quand il faut prendre par la main l’ensemble du personnel. A mon sens ces histoires de subtilités/performances du langage sont vraiment du ressort de quelques fans internautes hyperactifs (non que ce soit péjoratif, loin de là, d’ailleurs j’en fais parti hein, mais plutôt que c’est une infime minorité).
A titre d’exemple, j’ai vu une personne « experte » nouvelle techno/web/C# qui ne savait pas à quoi cela correspondait de catcher une exception. Dès qu’il voyait le mot exception dans une signature, il mettait toute la méthode appelante dans un grand try catch swallow. Et c’était une personne de référence dans l’équipe, le reste étant moins compétent. Au final d’ailleurs cette personne est très débrouillarde, seulement ce n’est pas sa passion, elle apprend sur le tas et avec le peu de formation donné. Il ne faut juste pas lui demander d’avoir l’esprit critique sur les technologies utilisée/la mise en oeuvre. Et au demeurant il n’a pas tort, dans une boite avec plus de 1000 développeurs, le développeur lambda n’a que peu voix au chapitre. Toujours à titre d’exemple, rares étaient ceux capables de dire quelle version de C# était utilisée (en fait seuls gars d’une équipe d’architecture). Alors introduire un java/C# non backward compatible dans de tels environnements, c’est vraiment chercher à se faire taper pour un éditeur comme Oracle.
A l’inverse, perso, tant que d’autres alternatives peuvent fleurir, ça me va. A titre pro, dans une boite bien moins conservatrice que l’exemple ci dessus certes, j’envisage de plus en plus Scala (je me pencherai dessus dès que j’ai un peu plus de temps, genre après le gros projet boulot en cours et.. le bébé à venir :)).
D’ailleurs, vous qui prônez un tel bouleversement, pourquoi ne pas se pencher plutôt sur quelque chose pour Scala, Groovy et autres Clojure ? J’espère que ce n’est pas par peur du changement
++
joseph
J’avais aussi pas mal réfléchi à ça et j’en était arrivé à quasiment aux même conclusions, au checked exceptions près, pour faire original.
Je m’étais même amusé à faire la nouvelle arborescence de mon API nettoyée
Vu l’ampleur du chantier que tu nous propose (notamment la suppression des primitifs au conséquences potentiellement cataclysmiques), tu aurais pu rajouter la réification des génériques au programme.
Au niveau des concepts courants à intégrer au langage, j’aurais aussi ajouté les singletons et les classes immuables.
Dans la pratique, les changements que tu proposes sont très lourds, et le mode d’évolution de Java est un handicap à ce niveau par rapport à certains langages qui sont assez libres en termes d’évolution.
Je ne vois pas la communauté java accepter autant de changement d’un coup. Avant de réussir à intégrer la moitié de ce que tu propose, il faudrait attendre le JDK 16.0 en 2028.
Je pense qu’il vaudrait mieux se contenter d’apporter à la JVM les modifications nécessaires pour gérer tous ces nouveau features sans qu’il soient utilisés par le langage Java lui même.
Ainsi on pourrait faire un tout nouveau langage reprenant la syntaxe Java autant que possible mais sans souci de compatibilité.
On aurait deux langages différents qui continueraient tous les deux a bénéficier des futures améliorations de l’API, sans ce soucier de la compatibilité de l’un avec l’autre.
@lunatix : sur le principe je suis d’accord avec toi, mais en pratique on trouve toujours des cas où on aurait aimer utiliser une unchecked à la place de la checked
Actuellement ce n’est pas possible (il faut catcher et remonter cela englobé dans une RuntimeException).
A l’inverse si tu as une unchecked-exception, tu es libre de traiter cela ou pas…
a++
Super intéressant,
en effet si on veut pouvoir faire évoluer le langage et alléger la syntaxe pour avoir quelque chose d’aussi agréable à utiliser que scala que les nouveaux langages de la jvm, il serait bon de casser un peu la compatibilité ascendante…
Pour les checked exceptions je suis d’accord pour dire que l’idée n’est pas mauvaise en soit, mais tellement utilisée dans l’API standard que le code en devient lourdingue (voire dangereux).
Pour moi, une checkedException est une exception pour laquelle on peut réagir intelligemment. (en gros en faisant autre chose que log and throw)
Par exemple, sur une api d’authentification, la checked exception est très bien. On doit réagir si on prends une IdentificationException. La checked Exception rends l’api beaucoup plus lisible en donnant dès le départ les cas d’erreurs fonctionnels (en gros)
sur JDBC… c’est une catastrophe, aucune action intelligente a faire sur une erreur de base de données. Ca doit se gerer de facon globale a l’appli, d’ou il aurait fallu des runtimes.
d’ou je suis d’accord avec : « principal soucis avec les checked-exceptions, c’est qu’elles sont un peu trop utilisées »
Le concept des checked-exceptions n’est pas mauvais en soit, mais il est très (trop) contraignant. En fait le principal soucis avec les checked-exceptions, c’est qu’elles sont un peu trop utilisées
Sinon j’ai du mal à voir ce que cela apporte sur le conception d’APIs métier en comparaison avec les unchecked-exceptions !
a++
Interessant. ca fait un moment que je pense qu’il faudrait faire ce genre de choses.
Il y a en plus pas mal de langages sur la jvm dont on peut s’inspirer (Phantom, stab, scala, etc..)
par contre, les checked exceptions, je suis pas convaincu, ça rends quand même bien service sur la conception d’apis métier. c’est pas parce que jdbc a été fait avec alors qu’il n’aurait pas fallu que le concept est mauvais.