
new
, og alt er klart :) Her skal vi snakke om hva som skjer inne i datamaskinen og Java-maskinen når vi skriver, for eksempel:
Cat cat = new Cat();
Vi har snakket om dette før, men i tilfelle vil vi minne deg på:
- Først tildeles minne for lagring av objektet.
- Deretter oppretter Java-maskinen en referanse til objektet (i vårt tilfelle er referansen Cat cat).
- Til slutt initialiseres variabler og konstruktøren kalles (vi skal se på denne prosessen mer detaljert).

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
er en implementering av en lastebil med felt som representerer år, modell og maksimal hastighet. Nå ønsker vi å lage et slikt objekt:
public class Main {
public static void main(String[] args) throws IOException {
Truck truck = new Truck(2017, "Scania S 500 4x2", 220);
}
}
For Java-maskinen vil prosessen se slik ut:
-
Det første som skjer er at de statiske variablene i
Vehicle
klassen initialiseres . Ja, jeg saVehicle
klassen, ikkeTruck
. Statiske variabler initialiseres før konstruktører kalles, og dette starter i den overordnede klassen. La oss prøve å bekrefte dette. Vi settervehicleCounter
feltet iVehicle
klassen lik 10 og prøver å vise det i både konstruktøreneVehicle
ogTruck
.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 har bevisst satt println-setningen helt i begynnelsen av konstruktøren
Truck
for å være sikker på at lastebilens felt ennå ikke er initialisert nårvehicleCounter
den vises.Og her er resultatet:
10 10
-
Etter at de statiske variablene til den overordnede klassen er initialisert, initialiseres de statiske variablene til underklassen. I vårt tilfelle er dette
truckCounter
klassens feltTruck
.La oss gjøre et nytt eksperiment der vi prøver å vise verdien av
truckCounter
inne iTruck
konstruktøren før de andre feltene initialiseres: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 verdien 10 allerede blitt tildelt vår statiske variabel når
Truck
konstruktøren begynner. -
Det er fortsatt ikke tid for konstruktørene! Variabel initialisering fortsetter. De ikke-statiske variablene til overordnet klasse initialiseres som tredje. Som du kan se, kompliserer arv betydelig prosessen med å lage et objekt, men det er ingenting du kan gjøre med det: Du må bare huske noen ting i programmering :)
Som et eksperiment kan vi tilordne en startverdi til variabelen
description
iVehicle
klassen, og deretter endre den i konstruktøren.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; } }
La oss kjøre
main()
metoden vår som lager en lastebil: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ølgende resultat:
Initial value of the description field Vehicle
Dette beviser at når
Vehicle
konstruktøren begynner,description
har feltet allerede blitt tildelt en verdi. -
Endelig er det tid for konstruktørene! Mer presist er det på tide med basisklassekonstruktøren. Det påkalles i det fjerde trinnet i objektopprettingsprosessen.
Dette er også ganske enkelt å verifisere. La oss prøve å sende ut to linjer til konsollen: en inne i
Vehicle
basisklassekonstruktøren, den andre inne iTruck
konstruktøren. Vi må være overbevist om at linjen på innsidenVehicle
vises 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 kjører
main()
metoden vår og ser på resultatet:Hello from the Vehicle constructor! Hello from the Truck constructor!
Utmerket. Det betyr at vi ikke tar feil :) La oss gå videre.
-
Nå er det tid for initialisering av de ikke-statiske feltene til barneklassen, altså vår
Truck
klasse. Feltene umiddelbart innenfor klassen som blir instansiert initialiseres ikke før det femte trinnet! Overraskende, men sant :) Igjen, vi vil gjøre en enkel sjekk — akkurat som med den overordnede klassen: vi tar en startverdi til variabelen,maxSpeed
og iTruck
konstruktøren sjekker vi at verdien ble tildelt før konstruktøren startet: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++; } }
Konsoll utgang:
Initial value of maxSpeed = 150
Som du kan se, når
Truck
konstruktøren starter,maxSpeed
er allerede lik 150! -
Konstruktøren av
Truck
barneklassen kalles.Og først på dette punktet, sist av alt, vil konstruktøren av klassen vi instansierer bli kalt!
Først i det sjette trinnet vil feltene bli tildelt verdiene som vi sender som argumenter til lastebilen vår.
Som du kan se, er det ikke enkelt å «konstruere» en lastebil, dvs. objektskapingsprosessen. Men det ser ut til at vi har delt det ned i de minste delene :)

GO TO FULL VERSION