Skip to content

Curiosidades Java: Operador instanceof

18 marzo 2009

Cuando utilicemos el operador instanceof, debemos recordar que sólo puede usarse con variables que contengan la referencia a un objeto. Es decir, variables que contendrán un conjunto de bytes que representarán a la dirección en memoria en la que está almacenado el objeto. Una variable de referencia normal ;)

El objetivo del operador instanceof es conocer si un objeto es de un tipo determinado. Por tipo nos referimos a clase o interfaz (interface), es decir si el objeto pasaría el test ES-UN para esa clase o ese interfaz, especificado a la derecha del operador.

Un ejemplo sería el siguiente:

String s = new String("No leas esto, sólo es un ejemplo");
if (s instanceof String)
     System.out.prinln("Efectivamente s pertenece a la clase String");

La salida sería: Efectivamente s pertenece a la clase String

Puede ocurrir que el objeto que estamos comprobando con instanceof, no sea una instancia directa de la clase que aparece a la derecha del operador, aun así instanceof devolverá true si el objeto es de un tipo compatible con el objeto que aparece a su derecha. Por ejemplo una instancia de una subclase. Esto se ve mejor con un ejemplo:

class Animal {}
class Perro extends Animal {
   public static void main (String[] args){
     Perro toby = new Perro();
     if (toby instanceof Animal)
       System.out.println("toby es un perro y también un animal");
   }
}

Esta comprobación puede resultar muy útil a la hora de hacer un downcast y asegurarnos de que se realizará sin problemas. Veamos un ejemplo, vamos a ampliar el ejemplo anterior:

class Animal {}
class Perro extends Animal {
   public static void main (String[] args){
     Perro toby = new Perro();
     if (toby instanceof Animal)
       System.out.println("toby es un perro y también un animal");

     Animal chusa = new Perro();  /* creacion */
     downCast(chusa);
   }
   public static void downCast(Animal a){
     if (a instanceof Perro)
       ((Perro)a).ladrar();
   }
   public static void ladrar(){
     System.out.println("Guau");
   }
}

Este código compilaría y produciría la salida: toby es un perro y tambien un animal y Guau

Veamos qué hace la línea creacion. Básicamente la JVM, lleva a cabo los siguientes pasos cuando llega a esta línea:

  1. Crea una variable de referencia llama chusa de tipo Animal
  2. Crea un objeto de tipo Perro
  3. Asigna el objeto Perro a la variable de referencia chusa

El punto 3, es totalmente posible, ya que Perro es una subclase de Animal y por tanto, todo objeto Perro, será también un objeto Animal. Pero al revés no!

Si hacemos: Animal mickey = new Animal();    Obtendremos que mickey NO es un perro.

Podemos realizar una deducción muy lógica: Cualquier referencia a un objeto que evaluemos con instanceof, resultará true si lo evaluamos frente al tipo Object.

Ya sabéis, en Java, todos los objetos son subclase de la clase Object o, dicho de otra forma, Object es superclase de cualquier objeto que creemos.

Lo mismo ocurre si en lugar de tener clases y subclases, implementamos interfaces. Por ejemplo, veamos el siguiente caso:

interface Nada {}
class A implements Nada {}
class B extends A {}

A a = new A();
B b = new B();
...

Las siguientes sentencias serían verdaderas:

a instanceof Nada
b instanceof A
b instanceof Nada  //Ya que b implementa el interfaz Nada, de manera indirecta

Al igual que hemos comentado antes con el caso especial de Object, tenemos el caso contrario. ¿Qué ocurre si hacemos null instanceof CualquierObjeto?

Efectivamente, el resultado siempre será false.

Error de compilación de instanceof

No podemos usar instanceof para tratar de comprobar dos clases de diferentes jerarquías. Por ejemplo el siguiente código provocaría un error de compilación:

class Gato {}
class Perro {
   public static void main (String[] args){
     Perro toby = new Perro();
     if (toby instanceof Gato)
       System.out.println("Esto no va a escribirlo");
   }
}
About these ads
12 comentarios leave one →
  1. 12 octubre 2009 22:40

    Muy buenos ejemplos!!!

  2. juan permalink
    3 marzo 2010 22:22

    Muy buena la explicacion me sirvio de mucho gracias!!!!!!

    • rekkeb permalink*
      4 marzo 2010 10:57

      De nada ;)

  3. hec permalink
    12 abril 2010 16:10

    MUY BUENO ME SIRVIO

  4. Minetaky permalink
    25 mayo 2010 06:43

    Hola! que buena explicacion, le entendí muy bien!, pero tengo una duda, se debe tener algún orden en la sintaxis, es que tengo un ejemplo:

    1. class Example {
    2. public static void main(String[] args) {
    3. Short s = 15;
    4. Boolean b;
    5. // insert code here
    6. }
    7. }

    Which, inserted independently at line 5, will compile? (Choose all that apply.)

    A b = (Number instanceof s);

    B b = (s instanceof Short);

    C b = s.instanceof(Short);

    D b = (s instanceof Number);

    E b = s.instanceof(Object);

    F b = (s instanceof String);

    El libro dice que lo correcto es B y D, y que A está mal por que los operadores estan alrevés y tu no mencionas nada de un orden en tu articulo. Espero puedas responder, Gracias!

    • rekkeb permalink*
      25 mayo 2010 09:35

      Efectivamente debe haber un orden cuando escribes una sentencia con instanceof. Lo que aparezca a la izquierda de instanceof debe ser una referencia a un objeto. No puede ser el nombre de una clase.
      En la parte derecha de instanceof, ocurre todo lo contrario, no puede aparecer una referencia a una clase, sino que debe aparecer el nombre de la clase en sí.
      Recuerda que la finalidad de instanceof es comprobar en tiempo de ejecución si una determinada referencia, “apunta” a un objeto de una determinada clase o no.

      Gracias por el apunte!

  5. Mario permalink
    24 noviembre 2010 15:20

    Muchas Gracias! de mucha utilidad.

  6. arbi permalink
    13 diciembre 2010 13:37

    muy claros y simples , tengo examen el 16 de java en la olavide ,estamos a 13 , ya solo 2 dias y medio…

    • rekkeb permalink*
      13 diciembre 2010 21:20

      Mucho ánimo con ese examen ;)

  7. Jeik permalink
    2 marzo 2011 03:56

    wenas men, muy buena explicacion de verdad que lo haces muy bien :D, y me sirvio mucho yo tambien tengo examen, es en menos de 8 horas xD, en fin, la programacion me gusta mucho y me gustaria hacer contacto contigo, ya sabes, hablar sobre programacion ^^
    si quiere dejeme su correo por aqui, o, envieme un email a jeikmen@gmail.com
    desde colombia saludos!!

  8. LevanenG permalink
    7 mayo 2011 20:14

    Excelente artículo, me gusto mucho, estoy mirando la forma de heredar a una clase, la clase ‘Observable’ e implementar la interfaz ‘Observer’ en otra clase (Aprendiendo a manejar un controlador de manera elegante); si hay algún ejemplo en esta página, me gustaría verlo. Muchas gracias

  9. exequiel permalink
    1 noviembre 2011 16:30

    excelente me sirvio de mucho sin esto no sabria como diferenciar en el main cual de todas las subclases debo usar gracias

Deja un comentario

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

Seguir

Recibe cada nueva publicación en tu buzón de correo electrónico.

%d personas les gusta esto: