
new
och allt är klart :) Här ska vi prata om vad som händer inuti datorn och Java-maskinen när vi skriver, till exempel:
Cat cat = new Cat();
Vi har pratat om detta förut, men ifall vi ska påminna dig:
- Först tilldelas minne för att lagra objektet.
- Därefter skapar Java-maskinen en referens till objektet (i vårt fall är referensen Cat cat).
- Slutligen initieras variabler och konstruktorn anropas (vi ska titta på denna process mer i detalj).

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++;
}
}
Klassen Truck
är en implementering av en lastbil med fält som representerar dess år, modell och maxhastighet. Nu vill vi skapa ett sådant objekt:
public class Main {
public static void main(String[] args) throws IOException {
Truck truck = new Truck(2017, "Scania S 500 4x2", 220);
}
}
För Java-maskinen kommer processen att se ut så här:
-
Det första som händer är att klassens statiska variabler
Vehicle
initieras . Ja, jag saVehicle
klassen, inteTruck
. Statiska variabler initieras innan konstruktörer anropas, och detta börjar i den överordnade klassen. Låt oss försöka verifiera detta. Vi sättervehicleCounter
fältet iVehicle
klassen lika med 10 och försöker visa det i både konstruktörernaVehicle
och .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++; } }
Vi lägger medvetet println-satsen i början av konstruktören
Truck
för att vara säker på att lastbilens fält ännu inte har initialiserats närvehicleCounter
visas.Och här är resultatet:
10 10
-
Efter att de statiska variablerna för den överordnade klassen har initierats, initieras de statiska variablerna för den underordnade klassen. I vårt fall är detta
truckCounter
klassens områdeTruck
.Låt oss göra ett annat experiment där vi ska försöka visa värdet på
truckCounter
inutiTruck
konstruktorn innan de andra fälten initieras: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++; } }
Som du kan se har värdet 10 redan tilldelats vår statiska variabel när
Truck
konstruktorn börjar. -
Det är fortfarande inte dags för konstruktörerna! Variabel initiering fortsätter. De icke-statiska variablerna för moderklassen initieras tredje. Som du kan se komplicerar arv avsevärt processen att skapa ett objekt, men det finns inget du kan göra åt det: Du måste bara memorera några saker i programmering :)
Som ett experiment kan vi tilldela ett initialt värde till
description
variabeln iVehicle
klassen och sedan ändra det i konstruktorn.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; } }
Låt oss köra vår
main()
metod som skapar en lastbil:public class Main { public static void main(String[] args) throws IOException { Truck truck = new Truck(2017, "Scania S 500 4x2", 220); } }
Vi får följande resultat:
Initial value of the description field Vehicle
Detta bevisar att när
Vehicle
konstruktören börjardescription
har fältet redan tilldelats ett värde. -
Äntligen är det dags för konstruktörerna! Mer exakt är det dags för basklasskonstruktören. Det anropas i det fjärde steget av objektskapandeprocessen.
Detta är också ganska lätt att verifiera. Låt oss försöka mata ut två rader till konsolen: en inuti basklasskonstruktorn,
Vehicle
den andra inutiTruck
konstruktorn. Vi måste vara övertygade om att raden inutiVehicle
visas först: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++; }
Vi kör vår
main()
metod och tittar på resultatet:Hello from the Vehicle constructor! Hello from the Truck constructor!
Excellent. Det betyder att vi inte har fel :) Låt oss gå vidare.
-
Nu är det dags för initialisering av de icke-statiska fälten i barnklassen, dvs vår
Truck
klass. Fälten omedelbart inom klassen som instansieras initieras inte förrän i det femte steget! Överraskande, men sant :) Återigen, vi kommer att göra en enkel kontroll — precis som med den överordnade klassen: vi skaffar ett initialvärde till variabelnmaxSpeed
och iTruck
konstruktorn kontrollerar vi att värdet tilldelades innan konstruktorn startade: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++; } }
Konsolutgång:
Initial value of maxSpeed = 150
Som du kan se, när
Truck
konstruktören startar,maxSpeed
är redan lika med 150! -
Konstruktören av
Truck
barnklassen kallas.Och först vid denna tidpunkt, sist av allt, kommer konstruktören av klassen vi instansierar att kallas!
Först i det sjätte steget kommer fälten att tilldelas de värden som vi skickar som argument till vår lastbil.
Som du kan se är det inte enkelt att "konstruera" en lastbil, dvs processen för att skapa objekt. Men det verkar som att vi har delat upp det i de minsta delarna :)

GO TO FULL VERSION