Menu
Coddy logo textTech

O Operador instanceof

Parte da seção Programação Orientada a Objetos do Journey de Java da Coddy — lição 31 de 87.

A lição anterior mostrou que o downcasting pode falhar com uma ClassCastException se o objeto não for realmente o tipo para o qual você está convertendo. O operador instanceof resolve isso permitindo que você verifique o tipo de um objeto antes da conversão.

A sintaxe é direta: object instanceof ClassName retorna true se o objeto for uma instância dessa classe (ou de qualquer uma de suas subclasses):

Animal animal = new Dog();

if (animal instanceof Dog) {
    Dog dog = (Dog) animal;
    dog.bark();  // Seguro para chamar métodos específicos de Dog
}

Esta verificação evita erros de tempo de execução ao garantir que a conversão (cast) seja bem-sucedida. O operador também retorna true para tipos pai na hierarquia:

Dog dog = new Dog();
System.out.println(dog instanceof Dog);     // true
System.out.println(dog instanceof Animal);  // true
System.out.println(dog instanceof Object);  // true

Desde o Java 16, você pode combinar a verificação e o cast em uma única etapa usando pattern matching:

if (animal instanceof Dog dog) {
    dog.bark();  // 'dog' já está convertido e pronto para uso
}

Esta sintaxe mais limpa elimina a linha de cast separada. Observe que instanceof retorna false quando testado contra null, então você não precisa de uma verificação de nulo separada.

challenge icon

Desafio

Fácil

Vamos construir um sistema de inspeção de veículos que utiliza o operador instanceof para identificar e lidar com segurança com diferentes tipos de veículos. Você criará uma hierarquia de veículos e escreverá um código que verifica o tipo real de cada veículo antes de acessar seus recursos especializados.

Você organizará seu código em quatro arquivos:

  • Vehicle.java: Crie a classe base que todos os veículos compartilham. Todo veículo possui um campo model (String). Inclua um construtor para inicializá-lo, um método getter getModel() e um método inspect() que imprime: "Inspecting vehicle: " + model
  • Car.java: Crie uma classe que estende Vehicle. Carros têm um campo adicional numDoors (int). Use super para a inicialização do pai. Adicione um método checkDoors() que imprime: getModel() + " has " + numDoors + " doors"
  • Motorcycle.java: Crie outra classe que estende Vehicle. Motocicletas têm um campo hasSidecar (boolean). Adicione um método checkSidecar() que imprime getModel() + " has a sidecar" ou getModel() + " has no sidecar" dependendo do valor booleano.
  • Main.java: Aqui é onde o instanceof se torna essencial! Você receberá quatro entradas: um modelo de carro, número de portas, um modelo de motocicleta e se ela tem um sidecar (true/false).

    Crie um array de referências de Vehicle contendo um Car e uma Motorcycle. Em seguida, percorra o array e para cada veículo:

    • Chame o método base inspect()
    • Use instanceof para verificar se é um Car - se for, faça o downcast com segurança e chame checkDoors()
    • Use instanceof para verificar se é uma Motorcycle - se for, faça o downcast com segurança e chame checkSidecar()

Você receberá quatro entradas: o modelo do carro (String), número de portas (int), modelo da motocicleta (String) e se tem sidecar (boolean).

Sua saída deve mostrar quatro linhas - para cada veículo, você verá sua mensagem de inspeção seguida por sua verificação específica de tipo. O operador instanceof garante que você só chame métodos de Car em objetos Car reais e métodos de Motorcycle em Motorcycles reais, evitando qualquer ClassCastException!

Folha de consulta

O operador instanceof verifica se um objeto é uma instância de uma classe específica antes de realizar o casting:

Animal animal = new Dog();

if (animal instanceof Dog) {
    Dog dog = (Dog) animal;
    dog.bark();  // Seguro para chamar métodos específicos de Dog
}

O operador retorna true para a classe do objeto e todas as classes pai na hierarquia:

Dog dog = new Dog();
System.out.println(dog instanceof Dog);     // true
System.out.println(dog instanceof Animal);  // true
System.out.println(dog instanceof Object);  // true

Desde o Java 16, o pattern matching combina a verificação e o cast em uma única etapa:

if (animal instanceof Dog dog) {
    dog.bark();  // 'dog' já está com o cast feito e pronto para uso
}

O operador instanceof retorna false quando testado contra null, eliminando a necessidade de verificações de nulo separadas.

Experimente você mesmo

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Ler as entradas
        String carModel = scanner.nextLine();
        int numDoors = Integer.parseInt(scanner.nextLine());
        String motorcycleModel = scanner.nextLine();
        boolean hasSidecar = Boolean.parseBoolean(scanner.nextLine());
        
        // TODO: Criar um objeto Car com carModel e numDoors
        
        // TODO: Criar um objeto Motorcycle com motorcycleModel e hasSidecar
        
        // TODO: Criar um array de referências Vehicle contendo o Car e a Motorcycle
        
        // TODO: Percorrer o array e para cada veículo:
        // 1. Chamar o método inspect()
        // 2. Usar instanceof para verificar se é um Car, então fazer o downcast e chamar checkDoors()
        // 3. Usar instanceof para verificar se é uma Motorcycle, então fazer o downcast e chamar checkSidecar()
    }
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos