1 puntos por GN⁺ 2024-08-04 | 1 comentarios | Compartir por WhatsApp

Null-Restricted and Nullable Types (Preview)

Resumen

Una función preliminar del lenguaje que admite marcadores de nulidad que permiten o rechazan null en los tipos de Java.

Objetivos

  • Mejorar los tipos de referencia de Java para que los programadores puedan expresar si esperan o no referencias null
  • Admitir conversiones entre tipos con distintos atributos de nulidad y proporcionar advertencias sobre valores null mal manejados
  • Mantener compatibilidad con el código Java existente y permitir la adopción gradual de la nueva funcionalidad
  • Garantizar que las variables de tipos con restricción de null se inicialicen antes de su primera lectura
  • Hacer cumplir en tiempo de ejecución los tipos que rechazan null, incluso en clases compiladas por separado
  • Proporcionar los metadatos y las garantías de integridad necesarios para optimizaciones en tiempo de ejecución

No objetivos

  • No reinterpretar automáticamente el código existente
  • No exigir que todos los valores null se manejen explícitamente
  • No incluir cambios para tipos primitivos
  • No aplicar las mejoras del lenguaje a la biblioteca estándar

Motivación

  • En los programas Java, una variable de tipo String puede contener una referencia a un objeto String o un valor null
  • Como no se puede expresar claramente si una variable permite o no null, esto genera confusión y errores
  • Se necesitan herramientas para que los desarrolladores puedan indicar, como parte del tipo, si un valor null es esperado o no está permitido

Descripción

Atributos y marcadores de nulidad

  • Los tipos de referencia pueden expresar opcionalmente su nulidad
  • Foo! es un tipo con restricción de null que no incluye null
  • Foo? es un tipo anulable que incluye null
  • Por defecto, la nulidad de Foo no está especificada

Inicialización de campos y arreglos

  • Los campos o arreglos con restricción de null deben inicializarse antes de usarse
  • Si se intenta leer un campo con restricción de null que no fue inicializado, se produce una excepción

Nulidad de expresiones y conversiones

  • El compilador de Java determina la nulidad de cada expresión
  • Las conversiones de nulidad permiten manejar expresiones con distinta nulidad
  • Las conversiones de nulidad de estrechamiento pueden provocar un NullPointerException en tiempo de ejecución

Verificación de null en tiempo de ejecución

  • Cuando ocurre una conversión de nulidad de estrechamiento, se produce un NullPointerException

Nulidad de variables de tipo

  • Las variables de tipo también pueden expresar nulidad
  • Las variables de tipo con restricción de null y las anulables afirman una nulidad específica dentro del código genérico

Argumentos de tipo y límites

  • Los argumentos de tipo pueden expresar nulidad, y esto afecta la nulidad de la API
  • Los argumentos de tipo con nulidad incompatible pueden generar advertencias

Sobrescritura de métodos e inferencia de argumentos de tipo

  • La nulidad se ignora al determinar si las firmas de métodos son iguales
  • El tipo de retorno de un método sobrescrito puede convertirse mediante conversiones de nulidad

Advertencias del compilador

  • Crear un tipo con restricción de null puede generar nuevos errores en tiempo de compilación
  • Las conversiones de nulidad de estrechamiento, el uso de tipos ? en operaciones hostiles a null, etc., pueden generar advertencias

Compilación y representación en archivos de clase

  • La mayoría de los marcadores de nulidad se eliminan de los archivos de clase
  • El nuevo atributo NullRestricted indica que un campo no permite valores null

Reflexión principal

  • No existen literales Foo!.class ni Foo?.class
  • La nueva API RuntimeType describe en tiempo de ejecución las variantes con restricción de null

Cambios complementarios

  • La serialización tradicional no es compatible con campos y arreglos con restricción de null
  • javadoc incluye marcadores de nulidad
  • Las API java.lang.reflect.Type y javax.lang.model codifican la nulidad

Alternativas

  • Diversas herramientas de desarrollo del ecosistema Java implementan su propio seguimiento de nulidad
  • Otros lenguajes de programación rastrean la nulidad dentro del sistema de tipos
  • La aplicación de nulidad en tiempo de ejecución puede implementarse con verificaciones explícitas o llamadas a Objects.requireNonNull

Dependencias

  • Requiere Flexible Constructor Bodies (Second Preview)
  • Trabajos futuros como Null-Restricted Value Class Types (Preview) y JEP 402: Enhanced Primitive Boxing (Preview)

Resumen de GN⁺

  • Este JEP ofrece herramientas para manejar con claridad los valores null en Java, mejorando la estabilidad y legibilidad del código
  • La introducción de tipos con restricción de null y tipos anulables puede reducir errores causados por referencias null
  • Es compatible con el código existente y puede adoptarse de forma gradual, lo que da flexibilidad a los desarrolladores
  • En comparación con otros lenguajes, puede fortalecer la capacidad de Java para manejar null
  • Una herramienta con funcionalidad similar es la seguridad de nulidad de Kotlin

1 comentarios

 
GN⁺ 2024-08-04
Comentarios de Hacker News
  • Comparación de cómo C# y Kotlin manejan null

    • En C#, si se activa nullability en el proyecto, todas las variables se declaran por defecto como non-null
    • Kotlin es similar, pero no necesita backwards compatibility
    • Kotlin ofrece la capacidad de inicializar después una variable non-nullable no inicializada mediante la declaración lateinit var
  • Opiniones sobre la nueva propuesta

    • Las variables existentes se distinguen como nullable, explícitamente nullable y explícitamente non-nullable
    • El enfoque de C# parece mejor, especialmente porque no hace falta resolver los problemas de nullability en codebases legacy
    • Sin embargo, el enfoque de C# resalta de inmediato los problemas de nullability en la codebase
  • Preocupaciones sobre la conversión automática de nullness-narrowing

    • La conversión automática da una sensación equivocada
    • Hay casos en los que debería generar un error del compilador
    • La conversión explícita es más segura
  • Necesidad de una forma de marcar todas las variables como non-null por defecto

    • Se necesita una forma de marcar todas las variables como non-null a nivel de paquete o archivo
    • De lo contrario, se terminará usando la sintaxis T! en casi todas las variables, lo que complica el código
  • Necesidad de una función de optionality explícita a nivel de lenguaje en Java

    • Con base en la experiencia con Kotlin y Typescript, el soporte a nivel de lenguaje es mejor
    • Herramientas como NullAway en Java son engorrosas
  • Críticas a la decisión de no aplicar las mejoras del lenguaje a la biblioteca estándar

    • Por la experiencia usando PHP, interactuar con la biblioteca estándar es incómodo
    • Es necesario añadir esta expresividad a la biblioteca estándar
  • Necesidad de una forma sencilla de elevar advertencias de compilación a errores

    • Java es principalmente un lenguaje de tipos estáticos, por lo que no es buena idea introducir comportamiento dinámico
  • Necesidad de que por defecto todo sea non-nullable, immutable y de alcance reducido

    • Muchas decisiones de diseño nuevas abandonan el camino seguro por conveniencia inmediata
    • En muchos lenguajes y tecnologías, este problema provoca muchos errores
  • Experiencia con el manejo de null en el lenguaje Hack

    • En el sistema de tipos de Hack, nullness es una parte importante
    • Pregunta sobre arreglos nullable
    • En Java esto es problemático porque todo el código legacy asume nullability
  • Pregunta sobre si esta función puede aplicarse al SDK de Java

    • Duda sobre cómo podría aplicarse al código legacy
  • Enlaces relacionados