CodeGym /Java-blogg /Tilfeldig /Sekvens av handlinger under objektskaping
John Squirrels
Nivå
San Francisco

Sekvens av handlinger under objektskaping

Publisert i gruppen
Hei! Dagens leksjon vil være ganske... eh... mangefasettert :) i den forstand at vi vil dekke et bredt spekter av emner, men de vil alle forholde seg til objektskapingsprosessen . Sekvens av handlinger under opprettelse av objekter - 1Vi vil analysere det fra begynnelse til slutt: hvordan konstruktører kalles, hvordan og i hvilken rekkefølge felt (inkludert statiske felt) initialiseres osv. Vi har tidligere vært inne på noen av punktene som er omtalt i artikkelen, slik at du kan se over materialet på basisklasse-konstruktører . La oss først huske hvordan et objekt er opprettet. Du husker godt hvordan denne prosessen ser ut fra en utviklers synspunkt: han lager en klasse, skriver 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).
I tillegg, fra leksjonen om objektets livssyklus , husker du sannsynligvis at et objekt varer så lenge det er minst én referanse til det. Hvis det ikke er noen igjen, blir gjenstanden et bytte for søppelsamleren. Sekvens av handlinger under objektoppretting - 2Disse to første punktene bør ikke reise noen spesielle spørsmål. Minneallokering er en enkel prosess, og det er bare to mulige utfall: enten er det minne eller ikke :) Og å lage en kobling er ikke uvanlig. Men det tredje punktet representerer et helt sett med operasjoner utført i streng rekkefølge. Jeg er ikke en fan av å stappe etter tester, men du må forstå denne prosessen godt og du må huske denne operasjonssekvensen. Da vi snakket om prosessen med å lage objekter i tidligere leksjoner, visste du egentlig ikke noe om arv ennå, så det var problematisk å forklare noen ting. Nå vet du ganske mye, og vi kan endelig vurdere dette spørsmålet i sin helhet :) Så det tredje punktet sier " Til slutt initialiseres variabler og konstruktøren kalles. " Men i hvilken rekkefølge skjer alt dette? For en bedre forståelse, la oss lage to superenkle klasser - en forelder 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 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:
  1. Det første som skjer er at de statiske variablene i Vehicleklassen initialiseres . Ja, jeg sa Vehicleklassen, ikke Truck. Statiske variabler initialiseres før konstruktører kalles, og dette starter i den overordnede klassen. La oss prøve å bekrefte dette. Vi setter vehicleCounterfeltet i Vehicleklassen lik 10 og prøver å vise det i både konstruktørene 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 har bevisst satt println-setningen helt i begynnelsen av konstruktøren Truckfor å være sikker på at lastebilens felt ennå ikke er initialisert når vehicleCounterden vises.

    Og her er resultatet:

    
    10 
    10
    
  2. Etter at de statiske variablene til den overordnede klassen er initialisert, initialiseres de statiske variablene til underklassen. I vårt tilfelle er dette truckCounterklassens felt Truck.

    La oss gjøre et nytt eksperiment der vi prøver å vise verdien av truckCounterinne i Truckkonstruktø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 Truckkonstruktøren begynner.

  3. 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 descriptioni Vehicleklassen, 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 Vehiclekonstruktøren begynner, descriptionhar feltet allerede blitt tildelt en verdi.

  4. 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 Vehiclebasisklassekonstruktøren, den andre inne i Truckkonstruktøren. Vi må være overbevist om at linjen på innsiden 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 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.

  5. Nå er det tid for initialisering av de ikke-statiske feltene til barneklassen, altså vår Truckklasse. 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, maxSpeedog i Truckkonstruktø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!

  6. Konstruktøren av Truckbarneklassen 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 :)

Sekvens av handlinger under opprettelse av objekter - 3 Hvorfor er det så viktig å forstå denne prosessen godt? Tenk hvor uventet resultatet av å lage et vanlig objekt kan være hvis du ikke visste nøyaktig hva som skjedde "under panseret" :) Nå er det på tide å gå tilbake til kurset og fullføre noen oppgaver! Lykke til og se deg snart! :)
Kommentarer
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION