CodeGym /Blog Java /Random-ES /Operador de instancia de Java
Autor
Jesse Haniel
Lead Software Architect at Tribunal de Justiça da Paraíba

Operador de instancia de Java

Publicado en el grupo Random-ES
¡Hola! Hoy hablaremos sobre el operador instanceof , consideraremos ejemplos de cómo se usa y tocaremos algunos aspectos de su funcionamiento :) Ya se ha encontrado con este operador en los primeros niveles de CodeGym. ¿Recuerdas por qué lo necesitamos? Si no, no te preocupes. Recordemos juntos. El operador instanceof es necesario para verificar si un objeto al que hace referencia una variable X se creó en función de alguna clase Y. Eso suena simple. ¿Por qué hemos vuelto a este tema? En primer lugar, porque ahora está familiarizado con el mecanismo de herencia de Java y los demás principios de la programación orientada a objetos. El operador instanceof ahora será mucho más claro y veremos ejemplos más avanzados de cómo se usa. ¡Vamos!Cómo funciona el operador instanceof - 1Probablemente recuerde que el operador instanceof devuelve verdadero si la verificación se evalúa como verdadero, o falso si la expresión es falsa. En consecuencia, suele aparecer en todo tipo de expresiones condicionales ( if…else ). Comencemos con algunos ejemplos más simples:

public class Main {

   public static void main(String[] args) {

       Integer x = new Integer(22);

       System.out.println(x instanceof Integer);
   }
}
¿Qué crees que se mostrará en la consola? Bueno, aquí es obvio. :) El objeto x es un número entero, por lo que el resultado será verdadero . Salida de la consola: True Intentemos verificar si es una cadena :

public class Main {

   public static void main(String[] args) {

       Integer x = new Integer(22);

       System.out.println(x instanceof String); // Error!
   }
}
Tenemos un error. Y atención: ¡el compilador generó el error antes de ejecutar el código! Inmediatamente vio que Integer y String no se pueden convertir automáticamente entre sí y no están relacionados por herencia. En consecuencia, no se crea un objeto Integer basado en String . Esto es conveniente y ayuda a evitar errores extraños en tiempo de ejecución, por lo que el compilador nos ayudó aquí :) Ahora intentemos considerar ejemplos que son más difíciles. Ya que mencionamos la herencia, trabajemos con el siguiente pequeño sistema de clases:

public class Animal {

}

public class Cat extends Animal {

}

public class MaineCoon extends Cat {

}
Ya sabemos cómo se comporta instanceof cuando verificamos si un objeto es una instancia de una clase, pero ¿qué sucede si consideramos la relación padre-hijo? Por ejemplo, ¿qué crees que producirán estas expresiones?

public class Main {

   public static void main(String[] args) {

       Cat cat = new Cat();

       System.out.println(cat instanceof Animal);

       System.out.println(cat instanceof MaineCoon);

   }
}
Salida: Verdadero Falso La pregunta principal que debe responderse es exactamente cómo interpreta la instancia de 'objeto creado en base a una clase'. ' cat instanceof Animal ' se evalúa como true , pero seguramente podemos encontrar fallas en esa redacción. ¿ Por qué se crea un objeto Gato basado en la clase Animal ? ¿No se crea basándose únicamente en su propia clase? La respuesta es bastante simple, y es posible que ya lo hayas pensado. Recuerde el orden en que se llaman los constructores y se inicializan las variables al crear un objeto. Ya tratamos este tema en el artículo sobre constructores de clases . He aquí un ejemplo de esa lección:

public class Animal {

   String brain = "Initial value of brain in the Animal class";
   String heart = "Initial value of heart in the Animal class";

   public static int animalCount = 7700000;

   public Animal(String brain, String heart) {
       System.out.println("Animal base class constructor is running");
       System.out.println("Have the variables of the Animal class already been initialized?");
       System.out.println("Current value of static variable animalCount = " + animalCount);
       System.out.println("Current value of brain in the Animal class = " + this.brain);
       System.out.println("Current value of heart in the Animal class = " + this.heart);
       System.out.println("Have the variables of the Cat class already been initialized?");
       System.out.println("Current value of static variable catCount = " + Cat.catCount);

       this.brain = brain;
       this.heart = heart;
       System.out.println("Animal base class constructor is done!");
       System.out.println("Current value of brain = " + this.brain);
       System.out.println("Current value of heart = " + this.heart);
   }
}

public class Cat extends Animal {

   String tail = "Initial value of tail in the Cat class";

   static int catCount = 37;

   public Cat(String brain, String heart, String tail) {
       super(brain, heart);
       System.out.println("The Cat class constructor has started (The Animal constructor already finished)");
       System.out.println("Current value of static variable catCount = " + catCount);
       System.out.println("Current value of tail = " + this.tail);
       this.tail = tail;
       System.out.println("Current value of tail = " + this.tail);
   }

   public static void main(String[] args) {
       Cat cat = new Cat("Brain", "Heart", "Tail");
   }
}
Y si lo ejecuta en el IDE, la salida de la consola se verá así: El constructor de la clase base Animal se está ejecutando ¿Ya se inicializaron las variables de la clase Animal? Valor actual de variable estática animalCount = 7700000 Valor actual de cerebro en la clase Animal = Valor inicial de cerebro en la clase Animal Valor actual de corazón en la clase Animal = Valor inicial de corazón en la clase Animal Ya tiene las variables de la clase Gato sido inicializado? Valor actual de la variable estática catCount = 37 ¡El constructor de la clase base Animal está listo! Valor actual de cerebro = Cerebro Valor actual corazón = Corazón El constructor de la clase gato ha comenzado (El constructor Animal ya ha terminado) Valor actual de la variable estática catCount = 37 Valor actual de cola = Valor inicial de cola en la clase Gato Valor actual de cola = Cola Ahora, ¿te acuerdas? :) El constructor de la clase base, si hay una clase base, siempre se llama primero cuando se crea un objeto. El operador instanceof se guía por este principio cuando intenta determinar si un objeto A se creó en función de una clase B. Si se llama al constructor de la clase base, entonces no puede haber ninguna duda. Con la segunda comprobación, todo es más sencillo:

System.out.println(cat instanceof MaineCoon);
No se llamó al constructor de MaineCoon cuando se creó el objeto Cat , lo cual tiene sentido. Después de todo, MaineCoon es descendiente de Cat , no un antepasado. Y no es una plantilla para Cat . Vale, creo que lo tenemos claro. Pero, ¿qué pasa si hacemos esto?:

public class Main {

   public static void main(String[] args) {

       Cat cat = new MaineCoon();

       System.out.println(cat instanceof Cat);
       System.out.println(cat instanceof MaineCoon);


   }
}
Hmm... ahora eso es más difícil. Hablemos de ello. Tenemos una variable Cat a la que le asignamos un objeto MaineCoon . Por cierto, ¿por qué funciona eso? Podemos hacer eso, ¿verdad? Si podemos. Después de todo, cada MaineCoon es un gato. Si eso no está del todo claro, recuerde el ejemplo de ampliación de tipos primitivos:

public class Main {

   public static void main(String[] args) {

       long x = 1024;

   }
}
El número 1024 es corto : cabe fácilmente en una variable larga , ya que hay suficientes bytes para acomodarlo (¿recuerdas el ejemplo con las muñecas?). Un objeto descendiente siempre se puede asignar a una variable antecesora. Por ahora, solo recuerda esto, y en lecciones posteriores analizaremos cómo funciona. Entonces, ¿qué produce nuestro ejemplo?

Cat cat = new MaineCoon();
System.out.println(cat instanceof Cat);
System.out.println(cat instanceof MaineCoon);
¿ Qué comprobará la instancia de ? nuestra variable Gato o nuestro objeto MaineCoon ? La respuesta es esta pregunta es realmente simple. Solo necesita volver a leer la definición del operador: se necesita el operador instanceof para verificar si un objeto al que hace referencia una variable X se creó en función de alguna clase Y. El operador instanceof prueba el origen de un objeto, no el tipo de variable. Por lo tanto, en este ejemplo, nuestro programa mostrará verdadero en ambos casos: tenemos un objeto MaineCoon . Obviamente, se creó en base a la clase MaineCoon , pero se creó en base a Catclase de padres también!
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION