Menu
Coddy logo textTech

El operador instanceof

Parte de la sección Programación Orientada a Objetos del Journey de Java de Coddy — lección 31 de 87.

La lección anterior mostró que el downcasting puede fallar con una ClassCastException si el objeto no es realmente del tipo al que estás realizando el casting. El operador instanceof resuelve esto permitiéndote comprobar el tipo de un objeto antes de realizar el casting.

La sintaxis es sencilla: object instanceof ClassName devuelve true si el objeto es una instancia de esa clase (o de cualquiera de sus subclases):

Animal animal = new Dog();

if (animal instanceof Dog) {
    Dog dog = (Dog) animal;
    dog.bark();  // Es seguro llamar a métodos específicos de Dog
}

Esta comprobación evita errores en tiempo de ejecución al asegurar que la conversión (cast) tendrá éxito. El operador también devuelve true para los tipos padre en la jerarquía:

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 Java 16, puedes combinar la comprobación y el moldeado (cast) en un solo paso utilizando la coincidencia de patrones (pattern matching):

if (animal instanceof Dog dog) {
    dog.bark();  // 'dog' ya está convertido y listo para usar
}

Esta sintaxis más limpia elimina la línea de conversión separada. Ten en cuenta que instanceof devuelve false cuando se prueba contra null, por lo que no necesitas una comprobación de nulos separada.

challenge icon

Desafío

Fácil

Vamos a construir un sistema de inspección de vehículos que utiliza el operador instanceof para identificar y manejar de forma segura diferentes tipos de vehículos. Crearás una jerarquía de vehículos y escribirás código que verifique el tipo real de cada vehículo antes de acceder a sus funciones especializadas.

Organizarás tu código en cuatro archivos:

  • Vehicle.java: Crea la clase base que comparten todos los vehículos. Cada vehículo tiene un campo model (String). Incluye un constructor para inicializarlo, un método getter getModel() y un método inspect() que imprima: "Inspecting vehicle: " + model
  • Car.java: Crea una clase que extienda de Vehicle. Los coches tienen un campo adicional numDoors (int). Usa super para la inicialización del padre. Añade un método checkDoors() que imprima: getModel() + " has " + numDoors + " doors"
  • Motorcycle.java: Crea otra clase que extienda de Vehicle. Las motocicletas tienen un campo hasSidecar (boolean). Añade un método checkSidecar() que imprima getModel() + " has a sidecar" o getModel() + " has no sidecar" dependiendo del valor booleano.
  • Main.java: ¡Aquí es donde instanceof se vuelve esencial! Recibirás cuatro entradas: un modelo de coche, el número de puertas, un modelo de motocicleta y si tiene sidecar (true/false).

    Crea un array de referencias de Vehicle que contenga un Car y una Motorcycle. Luego, recorre el array y para cada vehículo:

    • Llama al método base inspect()
    • Usa instanceof para verificar si es un Car; si es así, realiza un downcast seguro y llama a checkDoors()
    • Usa instanceof para verificar si es una Motorcycle; si es así, realiza un downcast seguro y llama a checkSidecar()

Recibirás cuatro entradas: el modelo del coche (String), el número de puertas (int), el modelo de la motocicleta (String) y si tiene sidecar (boolean).

Tu salida debería mostrar cuatro líneas: para cada vehículo, verás su mensaje de inspección seguido de su comprobación específica de tipo. El operador instanceof garantiza que solo llames a los métodos de Car en objetos Car reales y a los métodos de Motorcycle en Motorcycles reales, ¡evitando cualquier ClassCastException!

Hoja de referencia

El operador instanceof comprueba si un objeto es una instancia de una clase específica antes de realizar la conversión (casting):

Animal animal = new Dog();

if (animal instanceof Dog) {
    Dog dog = (Dog) animal;
    dog.bark();  // Es seguro llamar a métodos específicos de Dog
}

El operador devuelve true para la clase del objeto y todas las clases padre en la jerarquía:

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 Java 16, la coincidencia de patrones (pattern matching) combina la comprobación y la conversión en un solo paso:

if (animal instanceof Dog dog) {
    dog.bark();  // 'dog' ya está convertido y listo para usar
}

El operador instanceof devuelve false cuando se prueba contra null, eliminando la necesidad de realizar comprobaciones de nulos por separado.

Pruébalo tú mismo

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Leer las entradas
        String carModel = scanner.nextLine();
        int numDoors = Integer.parseInt(scanner.nextLine());
        String motorcycleModel = scanner.nextLine();
        boolean hasSidecar = Boolean.parseBoolean(scanner.nextLine());
        
        // TODO: Crear un objeto Car con carModel y numDoors
        
        // TODO: Crear un objeto Motorcycle con motorcycleModel y hasSidecar
        
        // TODO: Crear un arreglo de referencias de Vehicle que contenga el Car y el Motorcycle
        
        // TODO: Recorrer el arreglo y para cada vehículo:
        // 1. Llamar al método inspect()
        // 2. Usar instanceof para verificar si es un Car, luego realizar un downcast y llamar a checkDoors()
        // 3. Usar instanceof para verificar si es un Motorcycle, luego realizar un downcast y llamar a checkSidecar()
    }
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos