
new
y 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).

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 Truck
clase 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í:
-
Lo primero que sucede es que se inicializan las variables estáticas de la
Vehicle
clase . Sí, dije laVehicle
clase, noTruck
. Las variables estáticas se inicializan antes de llamar a los constructores, y esto comienza en la clase principal. Tratemos de verificar esto. Establecemos elvehicleCounter
campo en laVehicle
clase igual a 10 e intentamos mostrarlo en los constructoresVehicle
yTruck
.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
Truck
constructor para asegurarnos de que los campos del camión aún no se hayan inicializado cuandovehicleCounter
se muestre.Y aquí está el resultado:
10 10
-
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
truckCounter
campo de laTruck
clase.Hagamos otro experimento en el que intentaremos mostrar el valor de
truckCounter
dentro delTruck
constructor 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
Truck
comienza el constructor. -
¡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
description
variable enVehicle
clase 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
Vehicle
constructor comienza, eldescription
campo ya tiene asignado un valor. -
¡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
Vehicle
constructor de la clase base y la segunda dentro delTruck
constructor. Necesitamos estar convencidos de que la línea interiorVehicle
se 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.
-
Ahora es el momento de la inicialización de los campos no estáticos de la clase secundaria, es decir, nuestra
Truck
clase. ¡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 lamaxSpeed
variable y en elTruck
constructor 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! -
Truck
Se 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 :)

GO TO FULL VERSION