W3docs

Operador instanceof en Java

Comprueba el tipo en tiempo de ejecución de un objeto con el operador instanceof y usa la coincidencia de patrones para instanceof.

instanceof hace una pregunta en tiempo de ejecución: "¿es esta referencia realmente un T (o un subtipo de T)?" La respuesta es un boolean, y la forma moderna de coincidencia de patrones también vinculará el valor a una variable tipada en un solo paso, por lo que no necesitas un cast separado.

Es la herramienta a la que recurres siempre que tienes una referencia polimórfica y necesitas preguntar cuál es el tipo concreto real — típicamente dentro de equals, al recorrer una estructura de datos heterogénea, o al trabajar con jerarquías selladas.

La forma básica

La sintaxis clásica es expression instanceof Type:

Object o = "hello";
if (o instanceof String) {
  String s = (String) o;
  System.out.println(s.length());
}

La comprobación devuelve true si o hace referencia a un String o cualquier subtipo, y false si o es null o apunta a un tipo de objeto diferente. null instanceof Anything siempre es false — una garantía pequeña pero útil.

Coincidencia de patrones para instanceof

Desde Java 16, instanceof acepta un patrón de tipo que declara una variable vinculada al tipo reducido en la misma expresión:

if (o instanceof String s) {
  System.out.println(s.length());   // no cast needed
}

Si la comprobación tiene éxito, s está en el ámbito y ya tiene el tipo String. Si falla, s no está en el ámbito. El cast desaparece, la redundancia desaparece, y no puedes hacer accidentalmente un cast de algo que la comprobación rechazó.

Ámbito de la variable vinculada

La variable vinculada está en el ámbito dondequiera que el compilador pueda demostrar que la comprobación tuvo éxito. Eso incluye la rama if, pero también fluye a través de && y hacia la negación del if:

if (o instanceof String s && s.length() > 3) { ... }   // s is in scope after && — also a String

if (!(o instanceof String s)) return;
System.out.println(s.length());   // s is in scope after the early return

Ese segundo patrón es especialmente conveniente para el estilo de cláusulas de guarda — reduce el tipo, sale si no coincidió, y usa el nombre vinculado libremente a continuación.

El lado opuesto es ||: el enlace no fluye a través de él, porque el lado derecho se ejecuta precisamente cuando la comprobación falló. o instanceof String s || s.length() > 0 no compila — s no está en el ámbito a la derecha del ||.

Restricciones sobre el tipo objetivo

El compilador rechaza comprobaciones que puede demostrar que son imposibles. "hello" instanceof Integer ni siquiera compila, porque String e Integer no están relacionados. Esto detecta errores tipográficos y restos de refactorizaciones en tiempo de compilación en lugar de en tiempo de ejecución.

También rechaza upcasts que no pueden fallar: Object o = ...; if (o instanceof Object) {} se marca como redundante.

En switch

La misma maquinaria de coincidencia de patrones está disponible en switch, donde realmente brilla en jerarquías selladas:

String describe(Object o) {
  return switch (o) {
    case Integer i  -> "int " + i;
    case String  s  -> "str of length " + s.length();
    case int[]   a  -> "array of " + a.length;
    case null       -> "nothing";
    default         -> "something else";
  };
}

Con un tipo sellado como selector, puedes eliminar el default y el compilador exigirá un caso para cada subtipo permitido — combina esto con clases selladas para obtener análisis de casos exhaustivo.

Cuándo usarlo — y cuándo no

Usa instanceof cuando el tipo es genuinamente desconocido y la respuesta cambia el comportamiento: implementando equals, procesando jerarquías selladas de unión etiquetada, recorriendo nodos AST. No lo uses como sustituto de un polimorfismo adecuado — una cadena de if (x instanceof A) ... else if (x instanceof B) ... sobre una jerarquía abierta es generalmente una señal de que un método virtual sobre el tipo haría el trabajo mejor.

Un ejemplo práctico

java— editable, runs on the server

Qué sigue

instanceof es uno de varios métodos a los que responde todo objeto Java. El siguiente capítulo amplía el enfoque para ver el conjunto completo — java.lang.Object, la clase raíz que todo tipo extiende silenciosamente, y los métodos que heredas de ella tanto si los querías como si no. Continúa en la clase Object de Java.

Práctica

Práctica
¿Qué te ahorra la coincidencia de patrones para `instanceof` (`if (o instanceof String s)`) en comparación con la forma clásica?
¿Qué te ahorra la coincidencia de patrones para `instanceof` (`if (o instanceof String s)`) en comparación con la forma clásica?
Was this page helpful?