CodeGym /Java blogg /Slumpmässig /Sekvens av åtgärder under objektskapande
John Squirrels
Nivå
San Francisco

Sekvens av åtgärder under objektskapande

Publicerad i gruppen
Hej! Dagens lektion kommer att vara ganska... eh... mångfacetterad :) i den meningen att vi kommer att täcka ett brett spektrum av ämnen, men de kommer alla att relatera till processen för att skapa objekt . Sekvens av åtgärder under objektskapande - 1Vi kommer att analysera det från början till slut: hur konstruktörer kallas, hur och i vilken ordning fält (inklusive statiska fält) initieras, etc. Vi har tidigare berört några av punkterna som diskuteras i artikeln, så att du kan titta över materialet på basklasskonstruktörer . Låt oss först komma ihåg hur ett objekt skapas. Du kommer väl ihåg hur den här processen ser ut ur en utvecklares synvinkel: han skapar en klass, skriver , newoch 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).
Dessutom, från lektionen om objektets livscykel kommer du förmodligen ihåg att ett objekt varar så länge som det finns minst en referens till det. Om det inte finns några kvar, blir föremålet ett offer för sophämtaren. Sekvens av åtgärder under objektskapande - 2Dessa två första punkter bör inte väcka några speciella frågor. Minnestilldelning är en enkel process, och det finns bara två möjliga resultat: antingen finns det minne eller så finns det inte :) Och att skapa en länk är inte ovanligt. Men den tredje punkten representerar en hel uppsättning operationer som utförs i strikt ordning. Jag är inte ett fan av att fylla på med tester, men du måste förstå denna process väl och du måste memorera den här operationssekvensen. När vi pratade om processen för att skapa objekt i tidigare lektioner visste du inte riktigt något om arv ännu, så att förklara vissa saker var problematiskt. Nu vet du ganska mycket och vi kan äntligen överväga denna fråga i sin helhet :) Så den tredje punkten säger " Äntligen initieras variabler och konstruktorn anropas. " Men i vilken ordning sker allt detta? För en bättre förståelse, låt oss skapa två superenkla klasser - en förälder och ett 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 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:
  1. Det första som händer är att klassens statiska variabler Vehicleinitieras . Ja, jag sa Vehicleklassen, inte Truck. 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ätter vehicleCounterfältet i Vehicleklassen lika med 10 och försöker visa det i både konstruktörerna Vehicleoch .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 Truckför att vara säker på att lastbilens fält ännu inte har initialiserats när vehicleCountervisas.

    Och här är resultatet:

    
    10 
    10
    
  2. 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 truckCounterklassens område Truck.

    Låt oss göra ett annat experiment där vi ska försöka visa värdet på truckCounterinuti Truckkonstruktorn 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 Truckkonstruktorn börjar.

  3. 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 descriptionvariabeln i Vehicleklassen 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 Vehiclekonstruktören börjar descriptionhar fältet redan tilldelats ett värde.

  4. Ä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, Vehicleden andra inuti Truckkonstruktorn. Vi måste vara övertygade om att raden inuti Vehiclevisas 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.

  5. Nu är det dags för initialisering av de icke-statiska fälten i barnklassen, dvs vår Truckklass. 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 variabeln maxSpeedoch i Truckkonstruktorn 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!

  6. Konstruktören av Truckbarnklassen 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 :)

Sekvens av åtgärder under objektskapande - 3 Varför är det så viktigt att förstå denna process väl? Föreställ dig hur oväntat resultatet av att skapa ett vanligt föremål kan bli om du inte visste exakt vad som hände "under huven" :) Nu är det dags att återvända till kursen och slutföra några uppgifter! Lycka till och vi ses snart! :)
Kommentarer
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION