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 do tipo para o qual você está fazendo a conversão. O operador instanceof resolve isso permitindo que você verifique o tipo de um objeto antes de fazer a conversão.
A sintaxe é simples: 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 chamar métodos específicos de Dog
}Essa verificação evita erros em tempo de execução, garantindo que a conversão será 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); // trueDesde o Java 16, você pode combinar a verificação e a conversão de tipo em uma única etapa usando a correspondência de padrões:
if (animal instanceof Dog dog) {
dog.bark(); // 'dog' já está convertido (cast) e pronto para uso
}Essa sintaxe mais limpa elimina a linha de conversão separada. Observe que instanceof retorna false quando testado com null, portanto, você não precisa de uma verificação separada de null.
Desafio
FácilVamos criar um sistema de inspeção de veículos que usa 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 compartilhada por todos os veículos. Todo veículo tem um campomodel(String). Inclua um construtor para inicializá-lo, um método gettergetModel()e um métodoinspect()que imprime:Inspecting vehicle: [model]Car.java: Crie uma classe que estende Vehicle. Os carros têm um campo adicionalnumDoors(int). Usesuperpara a inicialização da classe-pai. Adicione um métodocheckDoors()que imprime:[model] has [numDoors] doorsMotorcycle.java: Crie outra classe que estende Vehicle. As motocicletas têm um campohasSidecar(boolean). Adicione um métodocheckSidecar()que imprime[model] has a sidecarou[model] has no sidecar, dependendo do valor booleano.Main.java: É aqui queinstanceofse torna essencial! Você receberá quatro entradas: um modelo de carro, o número de portas, um modelo de motocicleta e se ela tem um sidecar (true/false).Crie um array de referências
Vehiclecontendo um Car e uma Motorcycle. Em seguida, percorra o array e, para cada veículo:- Chame o método base
inspect() - Use
instanceofpara verificar se é um Car — se for, faça o downcast com segurança e chamecheckDoors() - Use
instanceofpara verificar se é uma Motorcycle — se for, faça o downcast com segurança e chamecheckSidecar()
- Chame o método base
Você receberá quatro entradas: o modelo do carro (String), o número de portas (int), o modelo da motocicleta (String) e se ela tem um sidecar (boolean).
Sua saída deve mostrar quatro linhas — para cada veículo, você verá sua mensagem de inspeção seguida pela verificação específica do seu tipo. O operador instanceof garante que você chame métodos de Car apenas em Cars reais e métodos de Motorcycle apenas em Motorcycles reais, evitando qualquer ClassCastException!
Experimente você mesmo
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Ler entradas
String carModel = scanner.nextLine();
int numDoors = Integer.parseInt(scanner.nextLine());
String motorcycleModel = scanner.nextLine();
boolean hasSidecar = Boolean.parseBoolean(scanner.nextLine());
// TODO: Crie um objeto Car com carModel e numDoors
// TODO: Crie um objeto Motorcycle com motorcycleModel e hasSidecar
// TODO: Crie um array de referências Vehicle contendo o Car e o Motorcycle
// TODO: Percorra o array e para cada veículo:
// 1. Chame o método inspect()
// 2. Use instanceof para verificar se é um Car, então faça downcast e chame checkDoors()
// 3. Use instanceof para verificar se é um Motorcycle, então faça downcast e chame checkSidecar()
}
}
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
1Fundamentos de POO
Arquivos ExternosIntrodução à POOClasses vs ObjetosA Palavra-chave thisMétodosCampos (Atributos)Método ConstrutorSobrecarga de ConstrutorRecapitulação - Calculadora Simples4Herança
Herança Básica (extends)A Palavra-chave superSobrescrita de Método (@Override)Encadeamento de ConstrutoresA Classe ObjectHerança Simples e MultinívelPor que não há Herança Múltipla de ClassesRecapitulação - Hierarquia de Funcionários7Métodos Especiais e a Classe Object
Método toString()equals() e hashCode()Método clone()compareTo() e ComparableInterface ComparatorRecapitulação - Ordenação Personalizada2Modificadores de Acesso e Encapsulamento
Visão Geral dos Níveis de AcessoMétodos Getter e SetterOcultação de InformaçõesA Palavra-chave finalRecapitulação - Gerenciador de Conta Bancária5Polimorfismo
Fundamentos de Sobrecarga de MétodosSobrescrita de Métodos (Tempo de Execução)Upcasting e DowncastingO Operador instanceofClasses e Métodos AbstratosRecapitulação - Calculadora de Formas8Conceitos Avançados de OOP
Composição vs HerançaAgregação vs ComposiçãoClasses Internas, Aninhadas e AnônimasEnums e Métodos de EnumRecords (Java 16+)Classes Seladas (Java 17+)11Padrões de Projeto Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão BuilderPadrão ObserverPadrão Strategy3Propriedades de Classe e Membros Estáticos
Variáveis de Instância vs EstáticasMétodos EstáticosBlocos EstáticosConstantes (static final)Recapitulação - Contador e Utilitário6Interfaces e Classes Abstratas
Introdução às InterfacesImplementando InterfacesImplementação de Múltiplas InterfacesDefault e Static em InterfacesClasses Abstratas vs InterfacesInterfaces FuncionaisRecapitulação - Sistema de Pagamento9Generics
Introdução a GenericsClasses GenéricasMétodos GenéricosParâmetros de Tipos DelimitadosWildcards (?, extends, super)Recapitulação - Container Genérico12Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão CompositePadrão IteratorPratique por conta própria: Compilador de Java online