CodeGym/Java blog/Tilfældig/Sekvens af handlinger under oprettelse af objekter
John Squirrels
Niveau
San Francisco

Sekvens af handlinger under oprettelse af objekter

Udgivet i gruppen
Hej! Dagens lektion vil være ret... øh... mangefacetteret :) i den forstand, at vi vil dække en bred vifte af emner, men de vil alle relatere til objektskabelsesprocessen . Sekvens af handlinger under oprettelse af objekter - 1Vi vil analysere det fra start til slut: hvordan konstruktører kaldes, hvordan og i hvilken rækkefølge felter (inklusive statiske felter) initialiseres osv. Vi har tidligere været inde på nogle af de punkter, der er diskuteret i artiklen, så du kan se over materialet på basisklassekonstruktører . Lad os først huske, hvordan et objekt er skabt. Du husker godt, hvordan denne proces ser ud fra en udviklers synspunkt: han opretter en klasse, skriver new, og alt er klar :) Her vil vi tale om, hvad der sker inde i computeren og Java-maskinen, når vi skriver, for eksempel:
Cat cat = new Cat();
Vi har talt om dette før, men bare hvis vi skal minde dig om:
  • Først tildeles hukommelse til lagring af objektet.
  • Dernæst opretter Java-maskinen en reference til objektet (i vores tilfælde er referencen Cat cat).
  • Til sidst initialiseres variabler, og konstruktøren kaldes (vi skal se på denne proces mere detaljeret).
Derudover husker du sikkert fra lektionen om objektets livscyklus , at et objekt holder, så længe der er mindst én reference til det. Hvis der ikke er nogen tilbage, bliver genstanden et bytte for skraldesamleren. Sekvens af handlinger under oprettelse af objekter - 2Disse to første punkter bør ikke rejse særlige spørgsmål. Hukommelseallokering er en simpel proces, og der er kun to mulige udfald: enten er der hukommelse, eller også er der ikke :) Og at oprette et link er ikke usædvanligt. Men det tredje punkt repræsenterer et helt sæt af operationer udført i streng rækkefølge. Jeg er ikke fan af at proppe til test, men du skal forstå denne proces godt, og du skal huske denne sekvens af operationer. Da vi talte om processen til oprettelse af objekter i tidligere lektioner, vidste du ikke rigtig noget om arv endnu, så det var problematisk at forklare nogle ting. Nu ved du en hel del, og vi kan endelig overveje dette spørgsmål fuldt ud :) Så det tredje punkt siger " Til sidst initialiseres variabler, og konstruktøren kaldes. " Men hvilken rækkefølge sker alt dette i? For en bedre forståelse, lad os oprette to super enkle klasser - en forælder og et barn:
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 Trucker en implementering af en lastbil med felter, der repræsenterer dens årgang, model og maksimale hastighed. Nu vil vi oprette et sådant 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 processen se sådan ud:
  1. Det første, der sker, er, at klassens statiske variable Vehicleinitialiseres . Ja, jeg sagde Vehicleklassen, ikke Truck. Statiske variable initialiseres før konstruktører kaldes, og dette starter i den overordnede klasse. Lad os prøve at bekræfte dette. Vi sætter vehicleCounterfeltet i Vehicleklassen lig med 10 og forsøger at vise det i både konstruktørerne Vehicleog 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 satte bevidst println-sætningen helt i begyndelsen af ​​konstruktøren Truckfor at være sikker på, at lastbilens felter endnu ikke er blevet initialiseret, når vehicleCounterden vises.

    Og her er resultatet:

    10
    10
  2. Efter at de statiske variabler for den overordnede klasse er initialiseret, initialiseres de statiske variabler for den underordnede klasse. I vores tilfælde er dette truckCounterklassens felt Truck.

    Lad os lave endnu et eksperiment, hvor vi prøver at vise værdien af truckCounter​​inde i Truckkonstruktøren, før de andre felter 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, er værdien 10 allerede blevet tildelt vores statiske variabel, når Truckkonstruktøren begynder.

  3. Det er stadig ikke tid til konstruktørerne! Variabel initialisering fortsætter. De ikke-statiske variable i den overordnede klasse initialiseres som tredje. Som du kan se, komplicerer arv betydeligt processen med at skabe et objekt, men der er intet du kan gøre ved det: Du skal bare huske nogle ting i programmering :)

    Som et eksperiment kan vi tildele en begyndelsesværdi til variablen descriptioni Vehicleklassen og derefter ændre 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;
       }
    }

    Lad os køre vores main()metode, der skaber 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ølgende resultat:

    Initial value of the description field
    Vehicle

    Dette beviser, at når Vehiclekonstruktøren begynder, descriptioner feltet allerede blevet tildelt en værdi.

  4. Endelig er det tid til konstruktørerne! Mere præcist er det tid til basisklassekonstruktøren. Det påberåbes i det fjerde trin af objektoprettelsesprocessen.

    Dette er også ret nemt at verificere. Lad os prøve at udlæse to linjer til konsollen: en inde i basisklassekonstruktøren Vehicle, den anden inde i Truckkonstruktøren. Vi skal være overbevist om, at linjen indeni Vehiclevises 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ører vores main()metode og ser på resultatet:

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

    Fremragende. Det betyder, at vi ikke tager fejl :) Lad os komme videre.

  5. Nu er det tid til initialisering af de ikke-statiske felter i børneklassen, altså vores Truckklasse. Felterne umiddelbart inden for den klasse, der instantieres, initialiseres ikke før det femte trin! Overraskende, men sandt :) Igen laver vi et simpelt tjek — ligesom med den overordnede klasse: vi indlæser en startværdi til variablen, maxSpeedog i Truckkonstruktøren tjekker vi, at værdien blev tildelt, før konstruktøren startede:

    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++;
       }
    }

    Konsoludgang:

    Initial value of maxSpeed = 150

    Som du kan se,  når Truck konstruktøren starter, maxSpeed er det allerede lig med 150!

  6. Konstruktøren af Truck​​børneklassen kaldes.

    Og først på dette tidspunkt, sidst af alt, vil konstruktøren af ​​den klasse, vi instansierer, blive kaldt!

    Først i det sjette trin vil felterne blive tildelt de værdier, som vi sender som argumenter til vores lastbil.

    Som du kan se, er det ikke nemt at "konstruere" en lastbil, dvs. processen med at skabe objekter. Men det ser ud til, at vi har delt det op i de mindste dele :)

Sekvens af handlinger under oprettelse af objekter - 3 Hvorfor er det så vigtigt at forstå denne proces godt? Forestil dig, hvor uventede resultaterne af at skabe et almindeligt objekt kunne være, hvis du ikke vidste præcis, hvad der skete "under motorhjelmen" :) Nu er det tid til at vende tilbage til kurset og udføre nogle opgaver! Held og lykke og se dig snart! :)
Kommentarer
  • Populær
  • Ny
  • Gammel
Du skal være logget ind for at skrive en kommentar
Denne side har ingen kommentarer endnu