CodeGym/Blog Java/Random-ES/Secuencia de acciones durante la creación de objetos
Autor
Pavlo Plynko
Java Developer at CodeGym

Secuencia de acciones durante la creación de objetos

Publicado en el grupo Random-ES
¡Hola! La lección de hoy será bastante... eh... multifacética :) en el sentido de que cubriremos una amplia gama de temas, pero todos estarán relacionados con el proceso de creación de objetos . Secuencia de acciones durante la creación de objetos - 1Lo analizaremos de principio a fin: cómo se llaman los constructores, cómo y en qué orden se inicializan los campos (incluidos los campos estáticos), etc. el material en constructores de clase base . Primero, recordemos cómo se crea un objeto. Recuerdas bien cómo se ve este proceso desde el punto de vista de un desarrollador: crea una clase, escribe newy todo está listo :) Aquí hablaremos sobre lo que sucede dentro de la computadora y la máquina Java cuando escribimos, por ejemplo:
Cat cat = new Cat();
Ya hemos hablado de esto antes, pero por si acaso te lo recordamos:
  • Primero, se asigna memoria para almacenar el objeto.
  • A continuación, la máquina Java crea una referencia al objeto (en nuestro caso, la referencia es Cat cat).
  • Finalmente, las variables se inicializan y se llama al constructor (veremos este proceso con más detalle).
Además, de la lección sobre el ciclo de vida del objeto , probablemente recuerde que un objeto dura mientras haya al menos una referencia a él. Si no queda ninguno, entonces el objeto se convierte en presa del recolector de basura. Secuencia de acciones durante la creación de objetos - 2Estos dos primeros puntos no deberían suscitar ninguna pregunta especial. La asignación de memoria es un proceso simple, y solo hay dos resultados posibles: hay memoria o no hay :) Y crear un enlace no es inusual. Pero el tercer punto representa todo un conjunto de operaciones ejecutadas en estricto orden. No soy un fanático de abarrotarme para las pruebas, pero debes comprender bien este proceso y debes memorizar esta secuencia de operaciones.. Cuando hablamos sobre el proceso de creación de objetos en lecciones anteriores, todavía no sabía nada sobre la herencia, por lo que explicar algunas cosas fue problemático. Ahora sabes bastante y finalmente podemos considerar esta pregunta en su totalidad :) Entonces, el tercer punto dice " Finalmente, las variables se inicializan y se llama al constructor ". Pero, ¿en qué orden sucede todo esto? Para una mejor comprensión, creemos dos clases súper simples: un padre y un hijo:
public class Vehicle {

   public static int vehicleCounter = 0;

   private String description = "Vehicle";
   public Vehicle() {
   }

   public String getDescription() {
       return description;
   }
}

public class Truck extends Vehicle {

   private static int truckCounter = 0;

   private int yearOfManufacture;
   private String model;
   private int maxSpeed;

   public Truck(int yearOfManufacture, String model, int maxSpeed) {
       this.yearOfManufacture = yearOfManufacture;
       this.model = model;
       this.maxSpeed = maxSpeed;

       Vehicle.vehicleCounter++;
       truckCounter++;
   }
}
La Truckclase es una implementación de un camión con campos que representan su año, modelo y velocidad máxima. Ahora queremos crear uno de esos objetos:
public class Main {

   public static void main(String[] args) throws IOException {

       Truck truck = new Truck(2017, "Scania S 500 4x2", 220);
   }
}
Para la máquina Java, el proceso se verá así:
  1. Lo primero que sucede es que se inicializan las variables estáticas de laVehicle clase . Sí, dije la Vehicleclase, no Truck. Las variables estáticas se inicializan antes de llamar a los constructores, y esto comienza en la clase principal. Tratemos de verificar esto. Establecemos el vehicleCountercampo en la Vehicleclase igual a 10 e intentamos mostrarlo en los constructores Vehicley Truck.

    public class Vehicle {
    
       public static int vehicleCounter = 10;
       private String description = "Vehicle";
    
       public Vehicle() {
           System.out.println(vehicleCounter);
       }
    
       public String getDescription() {
           return description;
       }
    }
    
    public class Truck extends Vehicle {
    
       private static int truckCount = 0;
    
       private int yearOfManufacture;
       private String model;
       private int maxSpeed;
    
       public Truck(int yearOfManufacture, String model, int maxSpeed) {
           System.out.println(vehicleCounter);
           this.yearOfManufacture = yearOfManufacture;
           this.model = model;
           this.maxSpeed = maxSpeed;
    
           Vehicle.vehicleCounter++;
           truckCount++;
       }
    }

    Colocamos deliberadamente la declaración println al comienzo del Truckconstructor para asegurarnos de que los campos del camión aún no se hayan inicializado cuando vehicleCounterse muestre.

    Y aquí está el resultado:

    10
    10
  2. Después de inicializar las variables estáticas de la clase principal, se inicializan las variables estáticas de la clase secundaria. En nuestro caso, este es el truckCountercampo de la Truckclase.

    Hagamos otro experimento en el que intentaremos mostrar el valor de truckCounterdentro del Truckconstructor antes de que se inicialicen los otros campos:

    public class Truck extends Vehicle {
    
       private static int truckCounter = 10;
    
       private int yearOfManufacture;
       private String model;
       private int maxSpeed;
    
       public Truck(int yearOfManufacture, String model, int maxSpeed) {
           System.out.println(truckCounter);
           this.yearOfManufacture = yearOfManufacture;
           this.model = model;
           this.maxSpeed = maxSpeed;
    
           Vehicle.vehicleCounter++;
           truckCounter++;
       }
    }

    Como puede ver, el valor 10 ya se ha asignado a nuestra variable estática cuando Truckcomienza el constructor.

  3. ¡Todavía no es tiempo para los constructores! La inicialización de variables continúa. Las variables no estáticas de la clase principal se inicializan en tercer lugar. Como puede ver, la herencia complica significativamente el proceso de creación de un objeto, pero no hay nada que pueda hacer al respecto: solo tiene que memorizar algunas cosas en la programación :)

    Como experimento, podemos asignar algún valor inicial a la descriptionvariable en Vehicleclase y luego cambiarlo en el constructor.

    public class Vehicle {
    
       public static int vehicleCounter = 10;
    
       private String description = "Initial value of the description field";
    
       public Vehicle() {
           System.out.println(description);
           description = "Vehicle";
           System.out.println(description);
       }
    
       public String getDescription() {
           return description;
       }
    }

    Ejecutemos nuestro main()método que crea un camión:

    public class Main {
    
       public static void main(String[] args) throws IOException {
    
           Truck truck = new Truck(2017, "Scania S 500 4x2", 220);
       }
    }

    Obtenemos el siguiente resultado:

    Initial value of the description field
    Vehicle

    Esto prueba que cuando el Vehicleconstructor comienza, el descriptioncampo ya tiene asignado un valor.

  4. ¡Finalmente, es hora de los constructores! Más precisamente, es hora del constructor de la clase base. Se invoca en el cuarto paso del proceso de creación de objetos.

    Esto también es bastante fácil de verificar. Intentemos enviar dos líneas a la consola: una dentro del Vehicleconstructor de la clase base y la segunda dentro del Truckconstructor. Necesitamos estar convencidos de que la línea interior Vehiclese muestra primero:

    public Vehicle() {
    
       System.out.println("Hello from the Vehicle constructor!");
    }
    
    public Truck(int yearOfManufacture, String model, int maxSpeed) {
    
       System.out.println("Hello from the Truck constructor!");
       this.yearOfManufacture = yearOfManufacture;
       this.model = model;
       this.maxSpeed = maxSpeed;
    
       Vehicle.vehicleCounter++;
       truckCounter++;
    }

    Ejecutaremos nuestro main()método y veremos el resultado:

    Hello from the Vehicle constructor!
    Hello from the Truck constructor!

    Excelente. Eso significa que no nos equivocamos :) Sigamos adelante.

  5. Ahora es el momento de la inicialización de los campos no estáticos de la clase secundaria, es decir, nuestra Truckclase. ¡Los campos inmediatamente dentro de la clase que se está instanciando no se inicializan hasta el quinto paso! Sorprendente, pero cierto :) Nuevamente, haremos una verificación simple, al igual que con la clase principal: le daremos un valor inicial a la maxSpeedvariable y en el Truckconstructor verificaremos que el valor se asignó antes de que comenzara el constructor:

    public class Truck extends Vehicle {
    
       private static int truckCounter = 10;
    
       private int yearOfManufacture;
       private String model;
       private int maxSpeed = 150;
    
       public Truck(int yearOfManufacture, String model, int maxSpeed) {
    
           System.out.println("Initial value of maxSpeed = " + this.maxSpeed);
           this.yearOfManufacture = yearOfManufacture;
           this.model = model;
           this.maxSpeed = maxSpeed;
    
           Vehicle.vehicleCounter++;
           truckCounter++;
       }
    }

    Salida de la consola:

    Initial value of maxSpeed = 150

    Como puede ver,  cuando se inicia el Truck constructor, maxSpeed ¡ya es igual a 150!

  6. TruckSe llama al constructor de la clase secundaria.

    Y solo en este punto, por último, ¡se llamará al constructor de la clase que estamos instanciando!

    Recién en el sexto paso se le asignarán a los campos los valores que le pasemos como argumentos a nuestro camión.

    Como puede ver, "construir" un camión, es decir, el proceso de creación de objetos, no es simple. Pero parece que lo hemos desglosado en las partes más pequeñas :)

Secuencia de acciones durante la creación de objetos - 3 ¿Por qué es tan importante entender bien este proceso? Imagínese lo inesperados que podrían ser los resultados de crear un objeto ordinario si no supiera exactamente lo que sucede "debajo del capó" :) ¡Ahora es el momento de volver al curso y completar algunas tareas! ¡Buena suerte y hasta pronto! :)
Comentarios
  • Populares
  • Nuevas
  • Antiguas
Debes iniciar sesión para dejar un comentario
Esta página aún no tiene comentarios