DEV Community

Java Efetivo (livro)
Java Efetivo (livro)

Posted on

Item 71: Evite o uso desnecessário das exceções verificadas

As exceções verificadas são uma ferramenta poderosa em Java, pois forçam o programador a tratar condições excepcionais, aumentando a confiabilidade do código. No entanto, seu uso excessivo pode tornar as APIs difíceis de usar. Para que uma exceção verificada seja justificada, a situação deve ser realmente excepcional e passível de uma ação útil por parte do programador. Caso contrário, uma exceção não verificada pode ser mais apropriada.

Java 8 trouxe um desafio adicional ao uso de exceções verificadas, uma vez que métodos que as lançam não podem ser usados diretamente em streams, exigindo tratamento adicional no código. Para evitar essa complexidade, pode-se considerar alternativas, como retornar um objeto Optional em vez de lançar uma exceção verificável, ou dividir o método em dois, um que verifica a possibilidade de erro e outro que realiza a operação.

Exceções verificadas devem ser usadas com moderação: se a recuperação não for possível, use exceções não verificadas. Quando a recuperação for viável, considere Optional para retorno. Se isso não fornecer informações suficientes, então uma exceção verificada pode ser justificada.

Plus:
Aqui estão alguns exemplos para ilustrar o uso adequado das exceções verificadas e alternativas, como Optional e o uso de métodos de verificação.

Usando Exceções Verificadas com Moderação
Digamos que temos um método que carrega dados de um arquivo. Se o arquivo não for encontrado, queremos lançar uma exceção para notificar o chamador do problema. Neste caso, uma exceção verificada é apropriada, pois o programador pode tomar uma ação para resolver o problema (como fornecer o caminho correto do arquivo).

public class FileLoader {
    public String loadFile(String filePath) throws FileNotFoundException {
        File file = new File(filePath);
        if (!file.exists()) {
            throw new FileNotFoundException("Arquivo não encontrado: " + filePath);
        }
        // Código para carregar o arquivo
        return "Conteúdo do arquivo";
    }
}

Enter fullscreen mode Exit fullscreen mode

Aqui, o chamador precisa lidar com a exceção FileNotFoundException, pois ele pode corrigir o problema informando um caminho correto para o arquivo.

Usando Optional em vez de Exceções Verificadas
Se a falta do arquivo for uma condição que não deve interromper a execução normal, podemos usar Optional para indicar que o resultado pode estar ausente sem lançar uma exceção. Isso torna a API mais fluida para casos onde uma ausência de valor pode ser tolerada.

import java.util.Optional;

public class FileLoader {
    public Optional<String> loadFile(String filePath) {
        File file = new File(filePath);
        if (!file.exists()) {
            return Optional.empty();
        }
        // Código para carregar o arquivo
        return Optional.of("Conteúdo do arquivo");
    }
}

Enter fullscreen mode Exit fullscreen mode

No código do chamador:

FileLoader loader = new FileLoader();
Optional<String> content = loader.loadFile("caminho/para/arquivo.txt");
content.ifPresentOrElse(
    System.out::println,
    () -> System.out.println("Arquivo não encontrado.")
);

Enter fullscreen mode Exit fullscreen mode

Neste exemplo, o chamador não precisa tratar exceções, e Optional permite que ele lide de maneira mais suave com a ausência de conteúdo.

Dividindo o Método em Dois: Verificação e Ação
Em alguns casos, podemos dividir o método em dois: um que verifica a condição e outro que executa a ação. Isso permite que o chamador trate a condição excepcional antes de chamar o método principal, tornando a API mais flexível.

public class FileLoader {
    // Verifica se o arquivo está disponível
    public boolean isFileAvailable(String filePath) {
        File file = new File(filePath);
        return file.exists();
    }

    // Carrega o conteúdo do arquivo
    public String loadFile(String filePath) {
        if (!isFileAvailable(filePath)) {
            throw new IllegalStateException("Arquivo não encontrado: " + filePath);
        }
        // Código para carregar o arquivo
        return "Conteúdo do arquivo";
    }
}

Enter fullscreen mode Exit fullscreen mode

No código do chamador:

FileLoader loader = new FileLoader();
String filePath = "caminho/para/arquivo.txt";

if (loader.isFileAvailable(filePath)) {
    String content = loader.loadFile(filePath);
    System.out.println(content);
} else {
    System.out.println("Arquivo não encontrado.");
}

Enter fullscreen mode Exit fullscreen mode

Aqui, usamos IllegalStateException, uma exceção não verificada, no caso em que o chamador tenta carregar o arquivo sem verificar antes se ele está disponível.

Resumo
Exceção Verificada: Use para condições que o chamador pode corrigir diretamente, como FileNotFoundException para arquivos.
Optional: Use quando a ausência de um valor não deve interromper o fluxo do programa.

Divisão de Métodos: Separe métodos de verificação e execução quando o erro puder ser previsto e evitado, tornando a API mais flexível e simples de usar.

Top comments (0)