Como Verificar se um Objeto Integer é Nulo em Java

JavaBeginner
Pratique Agora

Introdução

Neste laboratório, você aprenderá como lidar com segurança com objetos wrapper Integer em Java, focando especificamente em verificar se eles são null. Diferente do tipo primitivo int, Integer é um objeto que pode conter uma referência null, e não verificar se é null pode levar a erros comuns de NullPointerException.

Através de exemplos práticos, você explorará a verificação básica == null, combinará verificações de nulo com comparações de valores e, finalmente, aprenderá como aproveitar a classe Optional para um tratamento de nulo mais robusto e expressivo em seu código Java.

Testar Wrapper Integer para Nulo

Nesta etapa, exploraremos como lidar com objetos wrapper Integer em Java, focando especificamente em verificar se eles são null. Diferente dos tipos primitivos como int, Integer é uma classe, o que significa que uma variável Integer pode conter uma referência a um objeto, ou pode ser null se não se referir a nenhum objeto. Lidar com valores null é crucial em Java para evitar erros de NullPointerException, que são muito comuns e podem travar seu programa.

Vamos criar um programa Java simples para demonstrar a verificação de null com um Integer.

  1. Abra o arquivo HelloJava.java no editor WebIDE. Se você concluiu o laboratório anterior, este arquivo já deve existir no diretório ~/project.

  2. Substitua o código existente em HelloJava.java pelo seguinte:

    public class HelloJava {
        public static void main(String[] args) {
            Integer myInteger = null; // Declarando um Integer e definindo-o como null
    
            // Verifique se myInteger é null
            if (myInteger == null) {
                System.out.println("myInteger é null.");
            } else {
                System.out.println("myInteger não é null. Seu valor é: " + myInteger);
            }
    
            // Vamos tentar com um Integer não nulo
            Integer anotherInteger = 10; // Declarando e inicializando com um valor
    
            // Verifique se anotherInteger é null
            if (anotherInteger == null) {
                System.out.println("anotherInteger é null.");
            } else {
                System.out.println("anotherInteger não é null. Seu valor é: " + anotherInteger);
            }
        }
    }

    Neste código:

    • Declaramos uma variável Integer myInteger e a definimos explicitamente como null.
    • Usamos uma instrução if para verificar se myInteger é igual a null usando o operador ==. Esta é a maneira padrão de verificar se uma referência de objeto é null em Java.
    • Em seguida, declaramos outra variável Integer anotherInteger e atribuímos a ela o valor 10. Java converte automaticamente o valor primitivo int 10 em um objeto Integer (isso é chamado de autoboxing).
    • Realizamos a mesma verificação de null em anotherInteger.
  3. Salve o arquivo HelloJava.java (Ctrl+S ou Cmd+S).

  4. Agora, compile o programa usando o comando javac no Terminal. Certifique-se de estar no diretório ~/project.

    javac HelloJava.java

    Se não houver erros, a compilação será concluída silenciosamente e um arquivo HelloJava.class será criado no diretório ~/project.

  5. Execute o programa compilado usando o comando java:

    java HelloJava

    Você deve ver uma saída semelhante a esta:

    myInteger é null.
    anotherInteger não é null. Seu valor é: 10

    Esta saída confirma que nossa verificação de null funcionou corretamente tanto para o Integer null quanto para o Integer não null. Entender como verificar null é uma habilidade fundamental na programação Java, especialmente ao lidar com classes wrapper e objetos que podem nem sempre ter um valor atribuído.

Combinar Verificações de Nulo e Valor

Na etapa anterior, aprendemos como verificar se um objeto Integer é null. Frequentemente, você precisará verificar se um Integer não é null E se seu valor atende a uma determinada condição. Combinar essas verificações é importante porque tentar acessar o valor de um Integer null resultará em um NullPointerException.

Vamos modificar nosso programa para demonstrar a combinação de uma verificação de null com uma verificação de valor.

  1. Abra o arquivo HelloJava.java no editor WebIDE.

  2. Substitua o código existente pelo seguinte:

    public class HelloJava {
        public static void main(String[] args) {
            Integer score = null; // Exemplo 1: score é null
    
            // Verifique se score não é null E seu valor é maior que 50
            if (score != null && score > 50) {
                System.out.println("Score não é null e é maior que 50.");
            } else {
                System.out.println("Score é null ou não é maior que 50.");
            }
    
            Integer anotherScore = 75; // Exemplo 2: score é 75
    
            // Verifique se anotherScore não é null E seu valor é maior que 50
            if (anotherScore != null && anotherScore > 50) {
                System.out.println("anotherScore não é null e é maior que 50.");
            } else {
                System.out.println("anotherScore é null ou não é maior que 50.");
            }
    
            Integer yetAnotherScore = 40; // Exemplo 3: score é 40
    
            // Verifique se yetAnotherScore não é null E seu valor é maior que 50
            if (yetAnotherScore != null && yetAnotherScore > 50) {
                System.out.println("yetAnotherScore não é null e é maior que 50.");
            } else {
                System.out.println("yetAnotherScore é null ou não é maior que 50.");
            }
        }
    }

    Neste código atualizado:

    • Usamos o operador AND lógico (&&) para combinar duas condições: score != null e score > 50.
    • A verificação score != null é colocada primeiro. Em Java, o operador && usa avaliação de curto-circuito. Isso significa que se a primeira condição (score != null) for falsa, a segunda condição (score > 50) não será avaliada. Isso evita um NullPointerException quando score é null, porque o código score > 50 não seria executado.
    • Testamos essa lógica com três variáveis Integer diferentes: uma que é null, uma que não é null e é maior que 50, e uma que não é null, mas não é maior que 50.
  3. Salve o arquivo HelloJava.java.

  4. Compile o programa modificado no Terminal:

    javac HelloJava.java
  5. Execute o programa compilado:

    java HelloJava

    Você deve ver uma saída semelhante a esta:

    Score é null ou não é maior que 50.
    anotherScore não é null e é maior que 50.
    yetAnotherScore é null ou não é maior que 50.

    Esta saída demonstra como a verificação combinada funciona. O primeiro caso identifica corretamente que score é null. O segundo caso identifica que anotherScore não é null e é maior que 50. O terceiro caso identifica que yetAnotherScore não é maior que 50, embora não seja null. Este padrão de verificação de null antes de acessar as propriedades ou o valor de um objeto é uma prática fundamental de segurança em Java.

Usar Optional para Tratamento Seguro

Embora verificar null usando == null e combinar verificações com && seja eficaz, o Java 8 introduziu a classe Optional como uma maneira mais idiomática de lidar com valores que podem estar ausentes (ou seja, null). Optional é um objeto contêiner que pode ou não conter um valor não nulo. Usar Optional pode ajudar a tornar seu código mais legível e menos propenso a erros de NullPointerException.

Nesta etapa, vamos refatorar nosso programa para usar Optional<Integer> para lidar com valores inteiros potencialmente ausentes.

  1. Abra o arquivo HelloJava.java no editor WebIDE.

  2. Substitua o código existente pelo seguinte:

    import java.util.Optional;
    
    public class HelloJava {
        public static void main(String[] args) {
            // Exemplo 1: Optional contendo um valor nulo (Optional vazio)
            Optional<Integer> optionalScoreNull = Optional.empty();
    
            // Verifique se o Optional contém um valor e se é maior que 50
            if (optionalScoreNull.isPresent() && optionalScoreNull.get() > 50) {
                 System.out.println("optionalScoreNull está presente e é maior que 50.");
            } else {
                 System.out.println("optionalScoreNull está vazio ou não é maior que 50.");
            }
    
            // Exemplo 2: Optional contendo um valor não nulo (75)
            Optional<Integer> optionalScorePresent = Optional.of(75);
    
            // Verifique se o Optional contém um valor e se é maior que 50
            if (optionalScorePresent.isPresent() && optionalScorePresent.get() > 50) {
                 System.out.println("optionalScorePresent está presente e é maior que 50.");
            } else {
                 System.out.println("optionalScorePresent está vazio ou não é maior que 50.");
            }
    
            // Exemplo 3: Optional contendo um valor não nulo (40)
            Optional<Integer> optionalScoreNotGreater = Optional.of(40);
    
            // Verifique se o Optional contém um valor e se é maior que 50
            if (optionalScoreNotGreater.isPresent() && optionalScoreNotGreater.get() > 50) {
                 System.out.println("optionalScoreNotGreater está presente e é maior que 50.");
            } else {
                 System.out.println("optionalScoreNotGreater está vazio ou não é maior que 50.");
            }
    
            // Uma maneira mais funcional usando métodos Optional
            System.out.println("\nUsando métodos Optional:");
    
            optionalScoreNull.ifPresent(value -> System.out.println("Valor de optionalScoreNull: " + value));
            optionalScorePresent.ifPresent(value -> System.out.println("Valor de optionalScorePresent: " + value));
            optionalScoreNotGreater.ifPresent(value -> System.out.println("Valor de optionalScoreNotGreater: " + value));
    
            // Usando orElse para fornecer um valor padrão se Optional estiver vazio
            Integer scoreOrDefault = optionalScoreNull.orElse(0);
            System.out.println("Valor de optionalScoreNull com padrão: " + scoreOrDefault);
    
            // Usando filter para verificações condicionais
            optionalScorePresent.filter(value -> value > 50)
                                .ifPresent(value -> System.out.println("Valor filtrado de optionalScorePresent: " + value));
    
             optionalScoreNotGreater.filter(value -> value > 50)
                                .ifPresent(value -> System.out.println("Valor filtrado de optionalScoreNotGreater: " + value));
        }
    }

    Vamos analisar as principais mudanças:

    • import java.util.Optional;: Importamos a classe Optional.
    • Optional<Integer> optionalScoreNull = Optional.empty();: Criamos um Optional vazio para representar a ausência de um valor.
    • Optional<Integer> optionalScorePresent = Optional.of(75);: Criamos um Optional contendo um valor não nulo usando Optional.of(). Observe que Optional.of() lançará um NullPointerException se você passar um valor null. Se o valor puder ser null, use Optional.ofNullable().
    • optionalScoreNull.isPresent(): Este método verifica se o Optional contém um valor. É a maneira recomendada de verificar a presença em vez de verificar null.
    • optionalScoreNull.get(): Este método recupera o valor do Optional. Tenha cuidado! Se o Optional estiver vazio, chamar get() lançará um NoSuchElementException. É por isso que você sempre deve verificar isPresent() antes de chamar get(), ou usar outros métodos Optional que lidam com o caso vazio de forma adequada.
    • optionalScoreNull.ifPresent(value -> ...): Este método executa o código fornecido somente se o Optional contiver um valor. É uma maneira limpa de executar uma ação no valor, se ele existir.
    • optionalScoreNull.orElse(0): Este método retorna o valor se ele estiver presente, caso contrário, retorna o valor padrão especificado (0 neste caso).
    • optionalScorePresent.filter(value -> value > 50): Este método retorna um Optional contendo o valor se ele estiver presente E corresponder à condição dada (valor > 50), caso contrário, retorna um Optional vazio.
  3. Salve o arquivo HelloJava.java.

  4. Compile o programa no Terminal:

    javac HelloJava.java
  5. Execute o programa compilado:

    java HelloJava

    Você deve ver uma saída semelhante a esta:

    optionalScoreNull está vazio ou não é maior que 50.
    optionalScorePresent está presente e é maior que 50.
    optionalScoreNotGreater está vazio ou não é maior que 50.
    
    Usando métodos Optional:
    Valor de optionalScorePresent: 75
    Valor de optionalScoreNotGreater: 40
    Valor de optionalScoreNull com padrão: 0
    Valor filtrado de optionalScorePresent: 75

    Esta saída mostra como Optional pode ser usado para lidar com a presença ou ausência de valores e executar operações com segurança. Embora o padrão if (isPresent() && get() > 50) seja semelhante à verificação de null, Optional fornece muitos outros métodos úteis (ifPresent, orElse, filter, map, etc.) que podem levar a um código mais expressivo e seguro ao lidar com valores potencialmente ausentes. Usar Optional é uma boa prática no desenvolvimento Java moderno.

Resumo

Neste laboratório, aprendemos como verificar se um objeto wrapper Integer é null em Java. Começamos entendendo que Integer é uma classe e pode conter uma referência null, ao contrário do primitivo int. Demonstramos a verificação básica == null usando um programa Java simples, mostrando como lidar com variáveis Integer tanto null quanto não-null para evitar NullPointerException.