Vídeos novos: segunda, quarta e sexta · 8h

NullPointerException em Java: como evitar com Optional

Por que o NPE acontece e como o Optional deixa explícito quando um valor pode faltar.

O NullPointerException é provavelmente o erro mais famoso do Java. Ele acontece quando você tenta usar um objeto que, na verdade, é null:

Cliente cliente = repositorio.buscarPorEmail("ana@exemplo.com"); // devolveu null String cidade = cliente.getEndereco().getCidade(); // 💥 NullPointerException

O problema não é o null em si, e sim que nada no código avisava que ele podia aparecer. Desde o Java 14, a mensagem de erro ao menos diz qual parte da expressão era nula — mas o ideal é que o erro nem aconteça.

O que é Optional

Optional<T> é uma “caixa” que pode conter um valor ou estar vazia. Quando um método devolve Optional, ele está dizendo, no próprio tipo: “talvez não haja resultado — trate isso”.

public Optional<Cliente> buscarPorEmail(String email) { return clientes.stream() .filter(c -> c.getEmail().equals(email)) .findFirst(); }

No Spring Data JPA você já usa isso: findById devolve Optional.

Como tirar o valor da caixa

Optional<Cliente> resultado = repositorio.buscarPorEmail(email); // valor padrão Cliente c1 = resultado.orElse(Cliente.visitante()); // valor padrão calculado só se precisar Cliente c2 = resultado.orElseGet(() -> criarVisitante()); // lançar uma exceção com significado Cliente c3 = resultado.orElseThrow(() -> new ClienteNaoEncontradoException(email)); // executar algo só se existir resultado.ifPresent(c -> enviarBoasVindas(c));

Encadeando com map

O exemplo do início, aquele que explodia, fica seguro assim:

String cidade = repositorio.buscarPorEmail(email) .map(Cliente::getEndereco) .map(Endereco::getCidade) .orElse("Cidade não informada");

Se qualquer etapa estiver vazia, o resto é ignorado e cai no orElse.

Erros comuns com Optional

  • Chamar get() sem verificar. Isso só troca o NPE por um NoSuchElementException. Prefira orElseThrow().
  • Usar Optional em atributos ou parâmetros. Ele foi pensado para retornos de métodos.
  • Devolver null num método que retorna Optional. Use Optional.empty().
  • Embrulhar coleções. Em vez de Optional<List<T>>, devolva uma lista vazia.
Regra prática: se um método pode não ter resultado, devolva Optional. Se um valor nunca deveria ser nulo, valide cedo com Objects.requireNonNull.