I . Expressivité et la lisibilité de la logique du constructeur
Traditionnellement, les constructeurs Java devaient placer toute invocation explicite d’un autre constructeur comme première instruction.
Cette contrainte garantissait une exécution descendante et empêchait l’accès aux champs non initialisés, mais limitait considérablement l’expressivité et la lisibilité de la logique du constructeur.
Prenons l’exemple suivant :
public class ValeurPositive extends BigInteger public PositiveBigInteger(long valeur) super(valeur); if (valeur <= 0) throw new IllegalArgumentException("valeur non-positive");
Il serait préférable de déclarer un constructeur qui échoue rapidement en validant ses arguments avant d’invoquer le constructeur de la superclasse.
JEP 447 assouplit ces restrictions, permettant aux instructions qui ne font pas référence à l’instance en cours de création d’apparaître avant un invocation explicite du constructeur.
Avec cela, le code ci-dessus peut être simplifié comme suit :
public class ValeurPositive extends BigInteger public PositiveBigInteger(long valeur) if (valeur <= 0) throw new IllegalArgumentException("valeur non-positive"); super(valeur);
II . Préparation d’arguments pour un constructeur de superclasse par un « sous-classe »
Prenons un scénario dans lequel un constructeur de sous-classe doit préparer des arguments pour un constructeur de superclasse. Auparavant, cela nécessitait des méthodes auxiliaires en raison de la restriction liée à l’appel du constructeur de superclasse comme première instruction.
public class SubClass extends SuperClass public SubClass(Certificate certificat) super(prepareByteArray(certificat)); private static byte[] prepareByteArray(Certificate certificat) return byteArray;
Dans cet exemple, le prepareByteArray
méthode traite le Certificate
objet avant de le transmettre au SuperClass
constructeur. Avec JEP 447, ce processus devient plus simple et intuitif tels que l’exemple ci-dessous :
public class SubClass extends SuperClass public SubClass(Certificate certificat) PublicKey publicKey = certificate.getPublicKey(); if (publicKey == null) throw new IllegalArgumentException("Certificat nul"); byte[] byteArray = switch (publicKey) case RSAPublicKey rsaKey -> rsaKey.getEncoded(); case DSAPublicKey dsaKey -> dsaKey.getEncoded(); default -> throw new UnsupportedOperationException("Type de clé non pris en charge"); ; super(byteArray);
Dans cet exemple mis à jour, le constructeur de SubClass
inclut directement la logique pour traiter le Certificate
objet. Cette approche directe améliore la lisibilité et réduit le besoin de méthodes auxiliaires, démontrant les avantages pratiques du JEP 447 dans des scénarios réels.
Bien que la JEP 447 offre une plus grande flexibilité, elle préserve les garanties essentielles du comportement des constructeurs, garantissant que les constructeurs de sous-classes n’interfèrent pas avec l’instanciation des superclasses. Cette mise à jour ne nécessite aucune modification de la machine virtuelle Java (JVM), s’appuyant uniquement sur les capacités existantes de la JVM pour vérifier et exécuter le code d’appel pré-constructeur.
Alors que Java continue d’évoluer, JEP 447 est une indication claire de l’adaptation continue du langage aux pratiques de programmation modernes. Il reflète un équilibre entre l’introduction de nouvelles fonctionnalités et le maintien de la robustesse de l’écosystème Java. Pour les développeurs Java, cela signifie une opportunité d’explorer des pratiques de codage plus efficaces tout en restant ancrés dans les principes fondamentaux du langage.
Bien que la JEP 447 offre une plus grande flexibilité, elle préserve les garanties essentielles du comportement des constructeurs, garantissant que les constructeurs de sous-classes n’interfèrent pas avec l’instanciation des superclasses. Cette mise à jour ne nécessite aucune modification de la machine virtuelle Java (JVM), s’appuyant uniquement sur les capacités existantes de la JVM pour vérifier et exécuter le code d’appel pré-constructeur.
Alors que Java évolue sans cesse, JEP 447 indique précisément l’adaptation sur long terme du langage aux pratiques de programmation de nos jours.
Il est situé entre l’introduction de nouvelles fonctionnalités et le maintien de la force de l’écosystème de Java.
https://news-24.fr/affiner-les-constructeurs-java-pour-une-flexibilite-amelioree/