1 pontos por GN⁺ 2024-08-04 | 1 comentários | Compartilhar no WhatsApp

Null-Restricted and Nullable Types (Preview)

Resumo

Um recurso de linguagem em prévia que oferece suporte a marcadores de nullability para permitir ou rejeitar null em tipos Java.

Objetivos

  • Melhorar os tipos de referência do Java para que programadores possam expressar se esperam ou não referências null
  • Oferecer suporte a conversões entre tipos com diferentes propriedades de nullability e fornecer avisos sobre valores null tratados incorretamente
  • Manter compatibilidade com código Java existente e permitir a adoção gradual do novo recurso
  • Garantir que variáveis de tipos que rejeitam null sejam inicializadas antes da primeira leitura
  • Impor em runtime, inclusive em classes compiladas separadamente, os tipos que rejeitam null
  • Fornecer os metadados e as garantias de integridade necessários para otimizações em runtime

Não objetivos

  • Não reinterpretar automaticamente o código existente
  • Não exigir que todos os valores null sejam tratados explicitamente
  • Não incluir mudanças em tipos primitivos
  • Não aplicar as melhorias da linguagem à biblioteca padrão

Motivação

  • Em programas Java, uma variável do tipo String pode conter uma referência a um objeto String ou um valor null
  • Como não é possível expressar claramente se uma variável permite null ou não, isso gera confusão e bugs
  • É necessário oferecer ferramentas para que desenvolvedores possam declarar, como parte do tipo, se um valor null é suportado ou esperado

Descrição

Propriedades de nullability e marcadores

  • Tipos de referência podem expressar nullability opcionalmente
  • Foo! é um tipo com restrição de null, que não inclui null
  • Foo? é um tipo nulável, que inclui null
  • Por padrão, a nullability de Foo não é especificada

Inicialização de campos e arrays

  • Campos e arrays com restrição de null devem ser inicializados antes do uso
  • Se um campo com restrição de null não inicializado for lido, ocorrerá uma exceção

Nullability de expressões e conversões

  • O compilador Java determina a nullability de todas as expressões
  • Conversões de nullability permitem lidar com expressões que têm nullability diferente
  • Conversões de nullability por narrowing podem gerar NullPointerException em runtime

Verificação de null em runtime

  • Quando ocorre uma conversão de nullability por narrowing, é gerada uma NullPointerException

Nullability de variáveis de tipo

  • Variáveis de tipo também podem expressar nullability
  • Variáveis de tipo com restrição de null e variáveis de tipo nuláveis afirmam nullability específica dentro de código genérico

Argumentos de tipo e limites

  • Argumentos de tipo podem expressar nullability, e isso afeta a nullability da API
  • Argumentos de tipo com nullability incompatível podem gerar avisos

Sobrescrita de métodos e inferência de argumentos de tipo

  • A nullability é ignorada ao determinar se assinaturas de método são idênticas
  • O tipo de retorno de um método sobrescrito pode ser convertido por meio de conversão de nullability

Avisos do compilador

  • Tornar um tipo com restrição de null pode gerar novos erros em tempo de compilação
  • Conversões de nullability por narrowing e o uso de tipos ? em operações hostis a null, entre outros casos, podem gerar avisos

Compilação e representação em arquivos de classe

  • A maioria dos marcadores de null é removida nos arquivos de classe
  • O novo atributo NullRestricted indica que um campo não permite valores null

Core Reflection

  • Não existem literais Foo!.class nem Foo?.class
  • A nova API RuntimeType descreve a variante com restrição de null em runtime

Mudanças complementares

  • A serialização tradicional não é compatível com campos e arrays com restrição de null
  • O javadoc inclui marcadores de nullability
  • As APIs java.lang.reflect.Type e javax.lang.model codificam nullability

Alternativas

  • Diversas ferramentas do ecossistema Java implementam seu próprio rastreamento de null
  • Outras linguagens de programação rastreiam nullability no sistema de tipos
  • A imposição de nullability em runtime pode ser implementada com verificações explícitas ou chamadas a Objects.requireNonNull

Dependências

  • Requer Flexible Constructor Bodies (Second Preview)
  • Trabalho futuro como Null-Restricted Value Class Types (Preview) e JEP 402: Enhanced Primitive Boxing (Preview)

Resumo do GN⁺

  • Este JEP oferece ferramentas para lidar com valores null de forma clara no Java, aumentando a estabilidade e a legibilidade do código
  • A introdução de tipos com restrição de null e tipos nuláveis pode reduzir bugs causados por referências null
  • É compatível com código existente e pode ser adotado gradualmente, oferecendo flexibilidade para desenvolvedores
  • Em comparação com outras linguagens, pode fortalecer a capacidade do Java de lidar com null
  • Um recurso semelhante é a funcionalidade de null-safety do Kotlin

1 comentários

 
GN⁺ 2024-08-04
Comentários do Hacker News
  • Comparação entre as abordagens de tratamento de null em C# e Kotlin

    • No C#, quando a nullability é ativada no projeto, todas as variáveis são declaradas como non-null por padrão
    • O Kotlin é parecido, mas não precisa de backwards compatibility
    • O Kotlin oferece o recurso de inicializar depois uma variável non-nullable ainda não inicializada por meio da declaração lateinit var
  • Opiniões sobre a nova proposta

    • As variáveis existentes passam a ser classificadas como nullable, explicitamente nullable e explicitamente non-nullable
    • A abordagem do C# parece melhor, especialmente porque não é necessário resolver problemas de nullability em codebases legadas
    • Porém, a abordagem do C# destaca imediatamente os problemas de nullability na codebase
  • Preocupações com a conversão automática de nullness-narrowing

    • A conversão automática passa uma sensação errada
    • Há casos em que deveria gerar erro de compilação
    • Uma conversão explícita é mais segura
  • Necessidade de uma forma de marcar todas as variáveis como non-null por padrão

    • É preciso uma forma de marcar todas as variáveis como non-null no nível de pacote ou de arquivo
    • Caso contrário, a sintaxe T! acabará sendo usada em quase todas as variáveis, deixando o código mais complexo
  • Necessidade de um recurso de optionality explícita no nível da linguagem em Java

    • Com base na experiência em Kotlin e Typescript, o suporte no nível da linguagem é melhor
    • Ferramentas como NullAway no Java são incômodas
  • Crítica à decisão de não aplicar as melhorias da linguagem à biblioteca padrão

    • Pela experiência com PHP, a interação com a biblioteca padrão fica incômoda
    • É necessário adicionar esse poder de expressão à biblioteca padrão
  • Necessidade de uma forma fácil de promover avisos de compilação a erros

    • Como Java é principalmente uma linguagem de tipos estáticos, não é bom introduzir comportamento dinâmico
  • Necessidade de definir por padrão como non-nullable, immutable e de escopo estreito

    • Muitas novas decisões de design abrem mão do caminho seguro por conveniência imediata
    • Em muitas linguagens e tecnologias, esses problemas causam muitos erros
  • Experiência com tratamento de null na linguagem Hack

    • Nullness é uma parte importante do sistema de tipos de Hack
    • Há uma pergunta sobre arrays nullable
    • Em Java isso é problemático porque todo código legado assume nullability
  • Pergunta sobre a possibilidade de aplicar esse recurso ao Java SDK

    • Há dúvidas sobre como isso poderia ser aplicado a código legado
  • Links relacionados