¿Sabes cómo utilizar instanceof en Java 8? Con esta entrada comienzo una larga serie que va a abarcar todo el material que entra en el examen OCP de Oracle.
More...
La idea es ir preparándomelo a medida que publico las entradas, así voy aprendiendo sobre la marcha, y tú te puedes beneficiar de todas las explicaciones que yo te de aquí 🙂 . Ya he escrito antes una entrada sobre material que entra en el examen (en concreto, el artículo sobre el método toString()), pero a partir de ahora lo haré de manera sistemática.
Cómo utilizar instanceof en Java: ¿qué es instanceof?
instanceof es una palabra clave que significa, literalmente, instancia de. Sí, se escribe sin espacio.
Ya solo con esto puedes tener una pista de para qué se utiliza; básicamente, su función es la de determinar si el objeto al que apunta una referencia dada es una instancia de una clase o interfaz concretas. Así, instanceof devuelve un valor booleano (true/false, verdadero o falso).
Partes de instanceof en Java
Dicho lo anterior, instanceof consta de tres partes:
Ejemplo de uso de instanceof en Java
Uso de instanceof con clases
Ya basta de tanta letra, y pasemos al código. En primer lugar, comenzaremos con cómo utilizar instanceof en Java con instancias de una clase:
El objeto al que apunta la referencia perro es una instancia de la clase Perro, que hereda de la clase Animal. Entonces, el objeto al que apunta perro es una instancia también de la clase Animal. Por ello, el resultado es true.
Vaya, que toda instancia de la clase Perro es también una instancia de la clase Animal, porque todo Perro es un Animal.
Hasta ahora todo parece fácil, ¿no? Si el objeto al que apunta la referencia es una instancia de la clase, instanceof devuelve true. Me imagino que habrás observado que hablo continuamente de "el objeto al que apunta la referencia", y no de la referencia en sí. Esto se debe a que la referencia en sí no es nada; es como un hilo que nos lleva al objeto. La referencia en sí no es instancia de nada. Esto te tiene que quedar muy claro, porque es posible que, de otro modo, pienses que instanceof devuelva siempre el valor true si se utiliza la referencia perro que aparece más arriba. Nada más lejos de la realidad:
Como ves, la referencia perro no apunta a ningún objeto (null), y null no es instancia de nada.
null no es instancia de nada: devuelve false
El otro caso en el que instanceof devuelve false es cuando se utiliza una referencia de una superclase. Quedará más claro con un ejemplo:
En este caso, instanceof devuelve false porque la referencia es de tipo Animal, y puede apuntar tanto a un objeto de tipo Perro, como de tipo Gato. Quizá te digas "ya, lo he entendido, ¿qué otra cosa podría hacer instanceof?". La respuesta es muy fácil: podría no compilar.
Recuerda: instanceof solo devuelve false en dos casos
La razón es sencilla: cuando se utiliza una clase, como en este caso, instanceof solo devuelve false en dos casos:
En el resto de ocasiones, o el valor es true, o el código no compila. En realidad, puedes entenderlo de este modo: el código solo compila si el valor de instanceof es true. Si existen estas dos excepciones, es porque el compilador no sabe si la referencia es null, o a qué tipo de subclase apunta. Incluso si marcas la referencia como final, el código compila y devuelve false.
Si el objeto al que apunta la referencia ni es un Animal ni puede serlo, el código no compila:
Uso de instanceof con interfaces
En este caso, el uso de instanceof con interfaces es el mismo que con clases, con una pequeña diferencia: instanceof siempre compila. Cuando se utiliza instanceof, si el objeto al que apunta la referencia robot no es y no puede ser un objeto de clase Animal, ya que la clase Robot no la extiende, el compilador lo ve y detiene la compilación con un error.
En cambio, cuando se trata de una interfaz, el compilador no lo tiene tan claro. Veamos el siguiente ejemplo:
Si antes la clase Perro no podía ser una subclase de la clase Gato, ya que ambas extienden la clase Animal, en este caso es posible instanciar una referencia de la clase Robot, que no implementa la interfaz Blindaje, pero que apunte a un objeto cuyo tipo sea una subclase, Soldado, que sí lo implementa. Recuerda que una clase solo puede extender una clase, pero puede implementar un número ilimitado de interfaces. Como el compilador no puede distinguir uno de otro, permite que el código compile y que instanceof realice su labor.