DEV Community

Java Efetivo (livro)
Java Efetivo (livro)

Posted on

Item 55: Seja criterioso ao retornar opcionais

Abordagens pré-Java 8:

  • Lançar exceção: reservado para situações excepcionais e dispendioso devido à captura de rastreamento de pilha.
  • Retornar null: exige código especial para lidar com a possibilidade de retorno null, podendo causar erros como NullPointerException.

A abordagem do Java 8:

  • Introdução da classe Optional, um contêiner imutável que pode conter um valor ou estar vazio.
  • Evita o uso de null e simplifica o tratamento de valores ausentes sem lançar exceções.
  • Métodos podem retornar Optional para representar a ausência de um valor.

Vantagens do uso de Optional:

  • Evita exceções e problemas com null.
  • Permite que o cliente decida o que fazer quando o valor está ausente (fornecer valor padrão, lançar exceção, etc.).
  • Facilita o código sem a necessidade de tratamento explícito de null.

Métodos úteis da classe Optional:

  • Optional.of(value): cria um Optional com um valor não nulo.
  • Optional.ofNullable(value): cria um Optional, mas aceita valores nulos.
  • orElse(value): retorna um valor padrão se o Optional estiver vazio.
  • orElseThrow(): lança exceção se o valor não estiver presente.
  • map(), flatMap(), filter(): permitem manipulação de valores dentro do Optional.

Evite envolver coleções em Optional:

  • Para tipos de contêiner como listas ou arrays, retorne coleções vazias em vez de Optional>.

Considerações de desempenho:

  • O uso de Optional tem custo em termos de alocação de objetos.
  • Para tipos primitivos, use OptionalInt, OptionalLong e OptionalDouble para evitar o custo do empacotamento.

Cuidado com outros usos de Optional:
Evite usá-los como chaves ou valores de Map ou em coleções.
Evite usá-los como campos de instância, a menos que faça sentido, como em getters opcionais.

Exemplos de Código
Exemplo 1: Uso básico de Optional

import java.util.Optional;

public class ExemploOptional {
    public static Optional<String> encontrarNome(String[] nomes, String nomeBuscado) {
        for (String nome : nomes) {
            if (nome.equalsIgnoreCase(nomeBuscado)) {
                return Optional.of(nome);
            }
        }
        return Optional.empty();  // Retorna Optional vazio se não encontrar o nome
    }

    public static void main(String[] args) {
        String[] nomes = {"João", "Maria", "Ana"};
        Optional<String> nomeEncontrado = encontrarNome(nomes, "Maria");

        nomeEncontrado.ifPresent(nome -> System.out.println("Nome encontrado: " + nome));
        System.out.println(nomeEncontrado.orElse("Nome não encontrado"));
    }
}

Enter fullscreen mode Exit fullscreen mode

Exemplo 2: Uso de orElseThrow

import java.util.Optional;

public class ExemploOrElseThrow {
    public static Optional<Integer> buscarIdade(String nome) {
        if (nome.equals("João")) {
            return Optional.of(30);
        }
        return Optional.empty();  // Retorna Optional vazio se o nome não for "João"
    }

    public static void main(String[] args) {
        Optional<Integer> idade = buscarIdade("Maria");

        // Lança uma exceção se o valor não estiver presente
        int valorIdade = idade.orElseThrow(() -> new IllegalArgumentException("Idade não encontrada!"));
        System.out.println("Idade: " + valorIdade);
    }
}

Enter fullscreen mode Exit fullscreen mode

Exemplo 3: Optional com tipos primitivos

import java.util.OptionalInt;

public class ExemploOptionalInt {
    public static OptionalInt buscarIdade(String nome) {
        if (nome.equals("João")) {
            return OptionalInt.of(30);
        }
        return OptionalInt.empty();  // Retorna OptionalInt vazio se o nome não for "João"
    }

    public static void main(String[] args) {
        OptionalInt idade = buscarIdade("João");

        if (idade.isPresent()) {
            System.out.println("Idade encontrada: " + idade.getAsInt());
        } else {
            System.out.println("Idade não encontrada");
        }
    }
}

Enter fullscreen mode Exit fullscreen mode

Image of Bright Data

Global Data Access Unlocked – Reach data across borders without restrictions.

Unlock the power of global data collection with our advanced proxy solutions. Ideal for market research and more.

Unlock Data Now

Top comments (0)

Image of Bright Data

Ensure Data Quality Across Sources – Manage and normalize data effortlessly.

Maintain high-quality, consistent data across multiple sources with our efficient data management tools.

Manage Data

👋 Kindness is contagious

Dive into an ocean of knowledge with this thought-provoking post, revered deeply within the supportive DEV Community. Developers of all levels are welcome to join and enhance our collective intelligence.

Saying a simple "thank you" can brighten someone's day. Share your gratitude in the comments below!

On DEV, sharing ideas eases our path and fortifies our community connections. Found this helpful? Sending a quick thanks to the author can be profoundly valued.

Okay