Melhor verificação de nulos em Java

Scott Shipp Blocked Desbloquear Seguir Seguindo 4 de janeiro

Java executa alguns dos maiores sites e plataformas do mundo, mas muitas vezes luto com seu design como linguagem.

E ainda é uma ótima linguagem para fazer as coisas. Eu coloquei o Java em produção, onde ele lida com milhares de solicitações por segundo enquanto trabalha em empresas como Expedia e OpenMarket . O compilador Java, bem como excelentes ferramentas de desenvolvimento em um forte ecossistema em torno da linguagem, evita classes inteiras de erros de aplicativos.

Foto de Estée Janssens no Unsplash

Muito ruim, então, que a falha mais comum vista em um aplicativo Java seja o NullPointerException . Uma NullPointerException é lançada sempre que a JVM tenta desreferenciar uma variável e localiza nula em vez de um objeto. Como você pode evitar isso? A resposta é fácil: simplesmente não tem nenhuma variável apontando para null.

Infelizmente, o Java é uma linguagem desagradável que praticamente obriga o programador a criar (ou receber parâmetros de método) variáveis referenciando null. Qualquer variável declarada, mas não inicializada, faz referência automaticamente a null, e outras construções da linguagem Java, como as variáveis try / catch force, precisam ser declaradas em um escopo externo, em que null é uma das únicas opções válidas.

Aqui está um exemplo comum, de um dos tutoriais oficiais de Java , que é considerado bom Java:

Se houvesse outro código que usasse a variável out mais tarde, ele teria que executar a verificação nula (como visto na linha 19) novamente. Se out for usado com freqüência, o aplicativo pode estar cheio de verificação nula.

Soluções Alternativas

Eu tenho o que eu acho que é uma solução, mas quero mencionar brevemente algumas das formas existentes de lidar com isso, e porque eu acho que ainda precisamos de algo mais.

Opção 1: não anule a verificação.
Uma escola de pensamento é apenas não verificar nulo. Deixe o NullPointerException acontecer. Em seguida, tome medidas para remediar a causa subjacente. Por que eu nunca nulo verificar parâmetros de Robert Brautingham é um exemplo dessa filosofia.

Claro que concordo com esta escola de pensamento quando é realmente possível resolver a causa subjacente. Infelizmente, acredito que há muitas vezes em que a linguagem real força a verificação nula do programador. E se a língua não, a biblioteca de outra pessoa faz.

Foto de Marvin Meyer em Unsplash

Opção 2: use opcional.
Outra opção (ha ha, get it) é usar a classe Optional introduzida no Java 8. O Baeldung's Guide to Java 8 Optional cobre bem o uso. Ótima ideia, honestamente, se o código em questão estiver lidando com um fluxo . Isso é meio que o Optional foi feito e se você tem a opção (ok, ok, eu sei que isso está ficando um pouco pesado) vá em frente.

O que eu descobri, porém, é que há muitas situações em que a verificação de nulos inadequada foi substituída pelo uso ainda inábil do Opcional, como este exemplo de uma popular ferramenta Java de código aberto:

Isso realmente não é diferente do que a verificação nula neste código gêmeo:

 String pathsStr = get (PATHS_KEY); 
if (pathsStr! = null) {
ObjectMapper objectMapper = new ObjectMapper ();
experimentar {
String [] caminhos = objectMapper.readValue (pathsStr, String []. Class);

Exemplos como esses levaram muita da comunidade Java a declarar que o Optional.get é um Code Smell .

Um caminho melhor

Outras linguagens como Groovy e C # têm um bom operador condicional-nulo que permite ao programador especificar que uma cadeia de referências pode conter um nulo em algum lugar ao longo do caminho, e uma maneira natural de lidar com isso é apenas causar curto-circuito na cadeia de chama e resulta em um valor nulo.

Aqui está o primeiro exemplo da documentação do C #:

Java não permite a criação de operadores, portanto, não podemos imitar esse comportamento exatamente, mas usei alguns dos recursos funcionais encontrados no Java 8, como referências a métodos, para criar uma funcionalidade semelhante. Dê uma olhada.

Como um exemplo motivador, encontrar o código postal de um usuário em sua conta pode ser semelhante a isso no Java padrão:

São três verificações nulas no espaço de dez linhas.

Usando minha solução, que eu liberei como parte de uma biblioteca chamada Mill , o exemplo motivador pode ser convertido para :

Haveria então uma única verificação nula depois. Ou, se uma string vazia ou outro valor padrão puder ser mais aplicável, existe um método getOrDefault () alternativo. Há também um método getOrThrow () para quando uma exceção é mais apropriada.

Foto de Tanguy Sauvin em Unsplash

Mill é disponibilizado sob a licença MIT, então você está livre para pegar o jar e colocá-lo no classpath do seu aplicativo. Mill também possui vários recursos úteis relacionados a fluxo que podem tornar os fluxos mais fluentes e legíveis.

E se você é do tipo que contribui, Mill está aberto a contribuições. O repositório está disponível no Github . Estou pensando em distribuir para que seja fácil adicionar a um arquivo Maven ou Gradle. Mas todas as coisas no devido tempo e com a ajuda certa.

Um postscript

Tenho certeza de que, enquanto o Java viver, haverá verificação nula no código Java. A questão é que podemos fazer melhor do que o Java padrão permite? Acredito que a resposta seja sim, podemos e espero que, combinando algumas das várias abordagens mencionadas neste artigo, incluindo a classe NullSafe da Mill , possamos continuar a tornar nosso código de aplicativo mais elegante e evitar mais NullPointerExceptions em aplicativos Java.

scottashipp / mill
Biblioteca Java para tornar as tarefas comuns mais elegantes. Compatível com o Java 8+. – scottashipp / mill github.com