1 points par GN⁺ 2024-08-04 | 1 commentaires | Partager sur WhatsApp

Null-Restricted and Nullable Types (Preview)

Résumé

Fonctionnalité de langage en préversion prenant en charge des marqueurs de nullité qui autorisent ou refusent null dans les types Java.

Objectifs

  • Améliorer les types de référence de Java afin de permettre aux programmeurs d’exprimer s’ils attendent ou non une référence null
  • Prendre en charge les conversions entre des types ayant des propriétés de nullité différentes, et fournir des avertissements sur les valeurs null mal gérées
  • Rester compatible avec le code Java existant et permettre une adoption progressive de la nouvelle fonctionnalité
  • Garantir que les variables de type refusant null sont initialisées avant leur première lecture
  • Appliquer à l’exécution les types refusant null, y compris dans des classes compilées séparément
  • Fournir les métadonnées nécessaires et des garanties d’intégrité pour les optimisations à l’exécution

Non-objectifs

  • Ne pas réinterpréter automatiquement le code existant
  • Ne pas exiger un traitement explicite de toutes les valeurs null
  • Ne pas inclure de changements pour les types primitifs
  • Ne pas appliquer cette amélioration du langage à la bibliothèque standard

Motivation

  • Dans les programmes Java, une variable de type String peut contenir une référence vers un objet String ou la valeur null
  • Comme il n’existe pas de moyen clair d’exprimer si une variable autorise null ou non, cela entraîne de la confusion et des bugs
  • Il est nécessaire de fournir aux développeurs un outil leur permettant d’indiquer, comme partie du type, si une valeur null est attendue ou non prise en charge

Description

Propriétés de nullité et marqueurs

  • Les types de référence peuvent exprimer optionnellement la nullité
  • Foo! est un type à null restreint qui n’inclut pas null
  • Foo? est un type nullable qui inclut null
  • Par défaut, la nullité de Foo n’est pas spécifiée

Initialisation des champs et des tableaux

  • Les champs ou tableaux à null restreint doivent impérativement être initialisés avant utilisation
  • La lecture d’un champ à null restreint non initialisé provoque une exception

Nullité des expressions et conversions

  • Le compilateur Java détermine la nullité de chaque expression
  • Les conversions de nullité permettent de manipuler des expressions ayant des nullités différentes
  • Une conversion de nullité restrictive peut déclencher une NullPointerException à l’exécution

Vérification de null à l’exécution

  • Lorsqu’une conversion de nullité restrictive se produit, une NullPointerException est levée

Nullité des variables de type

  • Les variables de type peuvent aussi exprimer la nullité
  • Les variables de type à null restreint et nullable affirment une nullité spécifique dans le code générique

Arguments de type et bornes

  • Les arguments de type peuvent exprimer la nullité, ce qui influence la nullité de l’API
  • Des arguments de type dont la nullité ne correspond pas peuvent produire des avertissements

Redéfinition de méthodes et inférence des arguments de type

  • La nullité est ignorée pour déterminer si des signatures de méthode sont identiques
  • Le type de retour d’une méthode redéfinie peut être converti via une conversion de nullité

Avertissements du compilateur

  • Créer un type à null restreint peut introduire de nouvelles erreurs à la compilation
  • Les conversions de nullité restrictives, l’utilisation d’un type ? dans des opérations hostiles à null, etc., peuvent produire des avertissements

Compilation et représentation dans les fichiers de classe

  • La plupart des marqueurs de nullité sont supprimés des fichiers de classe
  • Un nouvel attribut NullRestricted indique qu’un champ n’accepte pas la valeur null

Core Reflection

  • Les littéraux Foo!.class et Foo?.class n’existent pas
  • La nouvelle API RuntimeType décrit à l’exécution les variantes à null restreint

Changements complémentaires

  • La sérialisation traditionnelle n’est pas compatible avec les champs et tableaux à null restreint
  • javadoc inclut les marqueurs de nullité
  • Les API java.lang.reflect.Type et javax.lang.model encodent la nullité

Alternatives

  • Divers outils de développement de l’écosystème Java implémentent déjà leur propre suivi de la nullité
  • D’autres langages de programmation suivent la nullité dans leur système de types
  • L’application de la nullité à l’exécution peut être implémentée avec des vérifications explicites ou des appels à Objects.requireNonNull

Dépendances

  • Flexible Constructor Bodies (Second Preview) est requis
  • Travaux futurs tels que Null-Restricted Value Class Types (Preview) et JEP 402: Enhanced Primitive Boxing (Preview)

Récapitulatif de GN⁺

  • Ce JEP fournit à Java des outils pour gérer plus explicitement les valeurs null, améliorant ainsi la robustesse et la lisibilité du code
  • L’introduction des types à null restreint et nullable peut réduire les bugs liés aux références null
  • La compatibilité avec le code existant et l’adoption progressive offrent de la flexibilité aux développeurs
  • Par comparaison avec d’autres langages, cela peut renforcer les capacités de Java en matière de gestion de null
  • Kotlin propose une fonctionnalité comparable avec sa null-safety

1 commentaires

 
GN⁺ 2024-08-04
Commentaires Hacker News
  • Comparaison des approches de C# et Kotlin pour la gestion de null

    • En C#, si la nullabilité est activée dans le projet, toutes les variables sont déclarées non nulles par défaut
    • Kotlin est similaire, mais n’a pas besoin de préserver la compatibilité ascendante
    • Kotlin permet aussi de déclarer une variable non nullable non initialisée puis de l’initialiser plus tard via lateinit var
  • Avis sur la nouvelle proposition

    • Les variables existantes sont distinguées entre nullable, explicitement nullable et explicitement non nullable
    • L’approche de C# semble meilleure, surtout parce qu’elle n’impose pas de résoudre les problèmes de nullabilité dans les bases de code legacy
    • Cependant, l’approche de C# met immédiatement en évidence les problèmes de nullabilité dans la base de code
  • Inquiétudes concernant les conversions automatiques de nullness narrowing

    • Les conversions automatiques donnent une impression trompeuse
    • Dans certains cas, il vaudrait mieux déclencher une erreur du compilateur
    • Une conversion explicite est plus sûre
  • Nécessité d’un moyen pour marquer toutes les variables comme non nulles par défaut

    • Il faut un moyen, au niveau du package ou du fichier, de marquer toutes les variables comme non nulles
    • Sinon, on finit par utiliser la syntaxe T! pour presque toutes les variables, ce qui alourdit le code
  • Besoin d’une fonctionnalité d’optionalité explicite au niveau du langage en Java

    • D’après l’expérience avec Kotlin et Typescript, un support au niveau du langage est préférable
    • Des outils comme NullAway en Java sont contraignants
  • Critique de la décision de ne pas appliquer ces améliorations du langage à la bibliothèque standard

    • D’après une expérience avec PHP, l’interaction avec la bibliothèque standard devient pénible
    • Il est nécessaire d’ajouter cette expressivité à la bibliothèque standard
  • Besoin d’un moyen simple pour promouvoir les avertissements de compilation en erreurs

    • Java étant principalement un langage à typage statique, introduire un comportement dynamique n’est pas souhaitable
  • Nécessité d’avoir par défaut des variables non nullables, immuables et à portée réduite

    • Beaucoup de nouvelles décisions de conception abandonnent la voie la plus sûre pour une commodité immédiate
    • Dans de nombreux langages et technologies, cela provoque énormément d’erreurs
  • Retour d’expérience sur la gestion de null dans le langage Hack

    • En Hack, la nullabilité est un élément important du système de types
    • Question sur les tableaux nullable
    • En Java, le problème vient du fait que tout le code legacy suppose la nullabilité
  • Question sur la possibilité d’appliquer cette fonctionnalité au SDK Java

    • Interrogation sur la façon de l’appliquer au code legacy
  • Liens associés