CodeGym/Blog Java/Aleatoriu/Secvența de acțiuni în timpul creării obiectului
John Squirrels
Nivel
San Francisco

Secvența de acțiuni în timpul creării obiectului

Publicat în grup
Bună! Lecția de astăzi va fi destul de... uh... multifațetă :) în sensul că vom acoperi o gamă largă de subiecte, dar toate se vor referi la procesul de creare a obiectelor . Secvența de acțiuni în timpul creării obiectului - 1O vom analiza de la început până la sfârșit: cum sunt chemați constructorii, cum și în ce ordine sunt inițializate câmpurile (inclusiv câmpurile statice) etc. Am atins anterior câteva dintre punctele discutate în articol, astfel încât să puteți arunca o privire peste materialul pe constructorii clasei de bază . Mai întâi, să ne amintim cum este creat un obiect. Vă amintiți bine cum arată acest proces din punctul de vedere al unui dezvoltator: el creează o clasă, scrie newși totul este gata :) Aici vom vorbi despre ce se întâmplă în interiorul computerului și a mașinii Java când scriem, de exemplu:
Cat cat = new Cat();
Am mai vorbit despre asta, dar în caz că vă reamintim:
  • În primul rând, este alocată memoria pentru stocarea obiectului.
  • Apoi, mașina Java creează o referință la obiect (în cazul nostru referința este Cat cat).
  • În cele din urmă, variabilele sunt inițializate și constructorul este apelat (vom analiza acest proces mai detaliat).
În plus, din lecția despre ciclul de viață al obiectului , probabil vă amintiți că un obiect durează atâta timp cât există cel puțin o referire la el. Dacă nu a mai rămas niciunul, atunci obiectul devine pradă pentru colectorul de gunoi. Secvența de acțiuni în timpul creării obiectului - 2Aceste prime două puncte nu ar trebui să ridice întrebări speciale. Alocarea memoriei este un proces simplu și există doar două rezultate posibile: fie există memorie, fie nu există :) Și crearea unei legături nu este neobișnuită. Dar al treilea punct reprezintă un întreg set de operații executate în ordine strictă. Nu sunt un fan al înghesuirii pentru teste, dar trebuie să înțelegeți bine acest proces și trebuie să memorați această secvență de operații. Când am vorbit despre procesul de creare a obiectelor în lecțiile anterioare, încă nu știai nimic despre moștenire, așa că explicarea unor lucruri a fost problematică. Acum știți destul de multe și în sfârșit putem lua în considerare această întrebare în întregime :) Deci, al treilea punct spune „ În sfârșit, variabilele sunt inițializate și constructorul este numit. ” Dar în ce ordine se întâmplă toate acestea? Pentru o mai bună înțelegere, să creăm două clase super simple — un părinte și un copil:
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++;
   }
}
Clasa Truckeste o implementare a unui camion cu câmpuri care reprezintă anul, modelul și viteza maximă. Acum vrem să creăm un astfel de obiect:
public class Main {

   public static void main(String[] args) throws IOException {

       Truck truck = new Truck(2017, "Scania S 500 4x2", 220);
   }
}
Pentru mașina Java, procesul va arăta astfel:
  1. Primul lucru care se întâmplă este că variabilele statice ale Vehicleclasei sunt inițializate . Da, am spus Vehicleclasa, nu Truck. Variabilele statice sunt inițializate înainte ca constructorii să fie apelați, iar aceasta începe în clasa părinte. Să încercăm să verificăm acest lucru. Setăm vehicleCountercâmpul din Vehicleclasă egal cu 10 și încercăm să îl afișam atât în ​​constructori, Vehiclecât și Truckîn constructori.

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

    Am pus în mod deliberat instrucțiunea println chiar la începutul constructorului Truckpentru a ne asigura că câmpurile camionului nu au fost încă inițializate când vehicleCountereste afișată.

    Și iată rezultatul:

    10
    10
  2. După ce variabilele statice ale clasei părinte sunt inițializate, variabilele statice ale clasei fii sunt inițializate. În cazul nostru, acesta este truckCounterdomeniul clasei Truck.

    Să facem un alt experiment în care vom încerca să afișăm valoarea din truckCounterinteriorul Truckconstructorului înainte ca celelalte câmpuri să fie inițializate:

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

    După cum puteți vedea, valoarea 10 a fost deja atribuită variabilei noastre statice când Truckîncepe constructorul.

  3. Inca nu este timpul pentru constructori! Inițializarea variabilei continuă. Variabilele non-statice ale clasei părinte sunt inițializate al treilea. După cum puteți vedea, moștenirea complică semnificativ procesul de creare a unui obiect, dar nu puteți face nimic în acest sens: trebuie doar să memorați câteva lucruri în programare :)

    Ca experiment, putem atribui o valoare inițială variabilei descriptiondin Vehicleclasă și apoi o putem schimba în constructor.

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

    Să rulăm main()metoda noastră care creează un camion:

    public class Main {
    
       public static void main(String[] args) throws IOException {
    
           Truck truck = new Truck(2017, "Scania S 500 4x2", 220);
       }
    }

    Obtinem urmatorul rezultat:

    Initial value of the description field
    Vehicle

    Acest lucru demonstrează că atunci când Vehicleconstructorul începe descriptioncâmpul i s-a atribuit deja o valoare.

  4. În sfârșit, este timpul pentru constructori! Mai precis, este timpul pentru constructorul clasei de bază. Este invocat în a patra etapă a procesului de creare a obiectului.

    Acest lucru este, de asemenea, destul de ușor de verificat. Să încercăm să scoatem două linii în consolă: una în Vehicleconstructorul clasei de bază, a doua în interiorul Truckconstructorului. Trebuie să fim convinși că linia din interior Vehicleeste afișată mai întâi:

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

    Vom rula main()metoda noastră și ne vom uita la rezultat:

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

    Excelent. Asta înseamnă că nu ne înșelim :) Să mergem mai departe.

  5. Acum este timpul pentru inițializarea câmpurilor non-statice ale clasei copil, adică Truckclasa noastră. Câmpurile imediat din clasa instanțiată nu sunt inițializate până la pasul al cincilea! Surprinzător, dar adevărat :) Din nou, vom face o verificare simplă - la fel ca în cazul clasei părinte: vom da o valoare inițială variabilei maxSpeedși în Truckconstructor vom verifica dacă valoarea a fost atribuită înainte de a începe constructorul:

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

    Ieșire din consolă:

    Initial value of maxSpeed = 150

    După cum puteți vedea,  când Truck pornește constructorul, maxSpeed este deja egal cu 150!

  6. Constructorul Truckclasei copil este numit.

    Și numai în acest moment, în sfârșit, va fi numit constructorul clasei pe care o instanțiem!

    Numai în pasul al șaselea câmpurilor li se vor atribui valorile pe care le transmitem ca argumente camionului nostru.

    După cum puteți vedea, „construirea” unui camion, adică procesul de creare a obiectelor, nu este simplă. Dar se pare că l-am împărțit în cele mai mici părți :)

Secvența de acțiuni în timpul creării obiectului - 3 De ce este atât de important să înțelegem bine acest proces? Imaginați-vă cât de neașteptate ar putea fi rezultatele creării unui obiect obișnuit dacă nu știați exact ce se întâmplă „sub capotă” :) Acum este timpul să reveniți la curs și să finalizați câteva sarcini! Succes și ne vedem curând! :)
Comentarii
  • Popular
  • Nou
  • Vechi
Trebuie să fii conectat pentru a lăsa un comentariu
Această pagină nu are încă niciun comentariu