C'est le moment idéal pour publier ceci, juste à la sortie de Java 19. Oui, un autre article "ma langue est meilleure". Non, je ne voulais pas l'écrire. Mais parfois, la mauvaise projection des gens prend le dessus sur moi. Dans ce cas, le message a commencé comme un commentaire et j'ai fini par décider de le transformer en message. Cela a été renforcé avec ce post qui se plaint principalement de Quarkus (un peu injustement si je puis ajouter).
Le premier article est principalement un appât à clics absurde et obsolète. Je vais vous résumer dans les affirmations suivantes :
[]
sur les collections et +
sur n'importe quoi
Le deuxième article contient des plaintes qui sont davantage liées à Jakarta EE et à l'esthétique générale des programmeurs dans la JVM. Plus précisément, l'utilisation d'annotations pour les validations et les revendications similaires. Il s'agit d'un article bien mieux informé, mais qui présente quelques défauts que j'aborderai vers la fin.
Les getters et les setters ne sont pas nécessaires pour Java moderne. Nous avons des records depuis Java 14 et Lombok est toujours bon malgré certaines affirmations contraires. Le seul point où nous aurions besoin de getter/setters est dans des contextes très spécifiques (par exemple JPA) où encore une fois, Lombok résout parfaitement le problème.
L'article s'appuie sur une tirade sur le manque de fonctionnalités de sucre syntaxique en Java. C'est intentionnel. Vous pouvez consulter Kotlin si vous êtes intéressé par les dernières nuances de syntaxe. Java est "lent et régulier". C'est une bonne chose et la principale raison de la longévité de Java.
Java moderne inclut des modèles dans switch, var, chaînes multilignes et bien plus encore. Certaines fonctionnalités à venir incluent des modèles de chaîne. La prise en charge des modèles de chaîne prend un certain temps car Java veut "faire les choses correctement". Il y a un certain support pour cela au niveau de l'API (et ce depuis un certain temps). Ce n'est pas performant. L'objectif des modèles de chaîne est de créer une syntaxe radicalement remplaçable qui permettrait des choses comme :
ResultSet rs = DB."SELECT * FROM Person p WHERE p.last_name = \{name}";
Mise à jour : depuis la publication de cet article, les développeurs ont supposé à tort que le code ci-dessus était une vulnérabilité d'injection SQL. Ce n'est pas le cas. Cela ressemble à un remplacement de chaîne, mais c'est du code qui utilise cette syntaxe pour générer un appel SQL paramétré.
Notez que name
est une variable que le compilateur vérifiera et obtiendra dynamiquement de la portée !
La base de DB
peut être implémentée de manière personnalisée par le développeur et n'a pas besoin d'être "intégrée", vous pouvez donc créer des modèles complexes directement sur place.
Mais parlons du Java que nous avons aujourd'hui, pas de celui qui arrivera dans 6 mois. L'utilisation d'append n'a pas été la recommandation pour String
depuis une décennie ou plus. Utilisez +
qui est le plus performant et le plus facile à lire. À propos des collections, la différence entre get()
et []
est littéralement de quatre caractères. Ces personnages comptent beaucoup. Nous pouvons facilement contourner cela. Nous pouvons également comprendre les différences sémantiques. Les tableaux Java sont TRÈS rapides, dans de nombreux cas, la vitesse native est rapide. Les collectes ne peuvent pas être aussi rapides, le fait que nous puissions voir cela ici instantanément est très précieux.
Le fait que les opérateurs ne puissent pas être surchargés est un énorme avantage. Si je vois a + b
, je sais qu'il s'agit soit d'une chaîne, soit d'un nombre, et non d'une méthode cachée. C'est l'une des plus grandes forces de Java et l'une des raisons pour lesquelles il est populaire depuis près de 30 ans alors que d'autres langages sont laissés de côté. La syntaxe de Java est conçue pour une lecture à grande échelle. Lorsque vous avez un projet avec 1 million de lignes de code ou même 100 000, les problèmes se déplacent. À ce stade, il est difficile de découvrir que le programmeur X du module Y a remplacé un opérateur de manière incorrecte lorsque vous déboguez un problème. La syntaxe doit être simple à ce stade et tout coût mineur que vous avez initialement économisé sera payé avec un intérêt de 10x. La définition des retournements simples en tant que code devient plus complexe et vieillit. Ajoutez à cela la puissance des outils pour analyser un code simple et strict à grande échelle et cela devient un avantage encore plus important.
Les exceptions cochées sont facultatives. Mais c'est l'une des MEILLEURES fonctionnalités de Java. Tant de code échoue de manière inattendue. Quand vous construisez des trucs comme passe-temps, ça peut aller. Lorsque vous souhaitez créer une application professionnelle, vous devez gérer chaque erreur. Les exceptions vérifiées vous aident à éviter ce non-sens. Les gens détestent les exceptions cochées à cause de la paresse. Java vous protège contre vous-même.
Il ne devrait y avoir aucun cas où j'établis une connexion réseau, une connexion DB, ouvre un fichier, etc. et n'ai pas besoin de gérer l'erreur potentielle. Je peux le lancer, mais les exceptions vérifiées m'obligent à continuer à le lancer quelque part. C'est une fonctionnalité incroyable.
J'ai beaucoup de problèmes avec Maven et Gradle. Mais quand vous le comparez à à peu près n'importe quel autre système de dépendance avec un peu de millage dessus, ils se débrouillent très bien. Ils ont des problèmes mais vous ne pouvez pas les comparer à quelque chose de jeune comme le fret qui n'a presque pas de colis en comparaison. Maven central est MASSIF avec 27 téraoctets de jars et 496 milliards de requêtes. Il fonctionne parfaitement et n'a presque pas de temps d'arrêt.
D'autres outils comme NPM démontrent parfaitement les points forts de maven. Si les dépendances dans maven posent problème, alors NPM a 100 fois le problème et aucune supervision. Au fur et à mesure que ces choses grandissent, il y a des complexités. Surtout avec plusieurs versions de maven sur le marché. Cependant, l'une des choses que maven et gradle ont pour eux est l'outillage. Dans de nombreux cas, les IDE aident à résoudre les problèmes et à trouver le correctif immédiatement.
Le deuxième article est plus intéressant et dans une certaine mesure, je suis d'accord. Les développeurs Java ont tendance à transformer chaque problème en un problème plus compliqué. Dans certains cas, cela est nécessaire, Java est le gorille de 800 livres des plates-formes de programmation et ses solutions sont souvent sur-conçues. Cela a tendance à être meilleur que sous-alimenté, mais cela a un prix.
L'article a soulevé un exemple intéressant qui semble être la "bonne chose" pour l'observateur occasionnel mais qui est problématique.
@NotNull @Email String noReplyEmailAddress
L'auteur prétend que c'est mauvais et qu'il faut implémenter un typage personnalisé, par exemple :
public record EmailAddress(String value) { public EmailAddress { // We could've used an Either data type, ofc; Objects.requireNonNull(value); // regexp could be better if (!value.matches("^[^@\\s]+@\\S+$")) throw new IllegalArgumentException( String.format("'%s' is not a valid email address", value)); } }
Ceci est tout à fait possible en Java car le code ci-dessus est un code Java valide. Mais il a plusieurs problèmes, c'est pourquoi nous avons la validation du bean.
Par conséquent, les annotations peuvent sembler bizarres et n'imposent pas la saisie. C'est vrai. Mais ils augmentent les performances et la puissance. Il y a beaucoup de réflexion et de bon sens derrière leur utilisation. Je comprends le point des auteurs, je ne suis pas non plus un grand fan d'IoC, mais dans ce cas précis, il a tort.
Cet article a passé beaucoup trop de temps sur la défensive. Il est temps de changer de vitesse. Java existe depuis près de 30 ans et est encore principalement compatible avec Java 1.0. C'est fantastique et incomparable !
L'un des pouvoirs de son approche conservatrice est qu'il peut faire d'étonnantes optimisations "sous le capot" sans qu'aucun d'entre vous ne remarque ce qui s'est passé. Java 9 a complètement remplacé la façon dont les chaînes étaient représentées en mémoire de manière transparente et a considérablement réduit l'utilisation de la RAM. De même, Loom augmentera le débit des applications synchrones Java. Valhalla améliorera encore les performances de collecte et unifiera le clivage Objet/Primitif. Panama va enfin nous débarrasser de JNI et rendre le processus d'intégration avec le code natif tellement plus agréable.
La bonne chose est que la JVM est une grande tente. Si vous n'êtes pas fan de Java, Kotlin ou Scala pourraient convenir à vos goûts. L'avantage de la JVM s'applique universellement et la plupart des fonctionnalités que j'ai mentionnées ici bénéficieront à l'ensemble de notre écosystème commun.
Cette histoire a été publiée pour la première fois ici.