1. Eigenschappen: getters en setters

Wanneer een groot project door tientallen programmeurs tegelijkertijd wordt ontwikkeld, ontstaan ​​er vaak problemen als zij anders omgaan met de gegevens die zijn opgeslagen in klassenvelden.

Misschien bestuderen mensen de klassendocumentatie niet in detail, of misschien beschrijft het niet elk geval. Als gevolg hiervan zijn er regelmatig situaties waarin de interne gegevens van een object "beschadigd" kunnen raken, waardoor het object ongeldig wordt.

Om deze situaties te voorkomen, is het gebruikelijk om alle klassenvelden in Java privé te maken . Alleen de methoden van de klasse kunnen de variabelen van de klasse wijzigen. Methoden uit andere klassen hebben geen directe toegang tot de variabelen.

Als u wilt dat andere klassen de gegevens in objecten van uw klasse kunnen ophalen of wijzigen, moet u twee methoden aan uw klasse toevoegen: een get-methode en een set-methode. Voorbeeld:

Code Opmerking
class Person
{
   private String name;

   public Person(String name)
   {
      this.name = name;
   }

   public String getName()
   {
      return name;
   }

   public void setName(String name)
   {
      this.name = name;
   }
}


privatenaamveld



Initialisatie van het veld via de constructor


getName()— Deze methode geeft de waarde van het naamveld terug




setName()— Deze methode verandert de waarde van het naamveld

Geen enkele andere klasse kan de waarde van het naamveld rechtstreeks wijzigen. Als iemand de waarde van het naamveld nodig heeft, moet hij de getName() methode op een Personobject aanroepen. Als een bepaalde code de waarde van het naamveld wil wijzigen, moet deze de setName() methode op een Personobject aanroepen.

De methode wordt ook wel de " getter voor het naamveld" getName()genoemd , en de methode wordt de " setter voor het naamveld" genoemd .setName()

Dit is een veel voorkomende benadering. In 80-90% van alle Java-code zie je nooit openbare variabelen in een klasse. In plaats daarvan worden ze gedeclareerd private(of protected) en heeft elke variabele openbare getters en setters.

Deze aanpak maakt de code langer, maar betrouwbaarder.

Rechtstreeks toegang krijgen tot een klassevariabele is als het draaien van je auto door dubbele gele lijnen : het is gemakkelijker en sneller, maar als iedereen het doet, wordt het voor iedereen erger.

Stel dat u een klasse wilt maken die een punt beschrijft ( x, y). Hier is hoe een beginnende programmeur het zou doen:

class Point
{
   public int x;
   public int y;
}

Hier is hoe een ervaren Java-programmeur het zou doen:

Code
class Point {
   private int x;
   private int y;

   public Point(int x, int y) {
      this.x = x;
      this.y = y;
   }

   public int getX() {
      return x;
   }

   public void setX(int x) {
      this.x = x;
   }

   public int getY() {
      return y;
   }

   public void setY(int y) {
      this.y = y;
   }
}

Is de code langer? Ongetwijfeld.

Maar u kunt parametervalidatie toevoegen aan getters en setters. U kunt er bijvoorbeeld voor zorgen dat xen yaltijd groter zijn dan nul (of niet kleiner dan nul). Voorbeeld:

Code Opmerking
class Point {
   private int x;
   private int y;

   public Point(int x, int y) {
      this.x = x < 0 ? 0 : x;
      this.y = y < 0 ? 0 : y;
   }

   public int getX() {
      return x;
   }

   public void setX(int x) {
      this.x = x < 0 ?  0 : x;
   }

   public int getY() {
      return y;
   }

   public void setY(int y) {
      this.y = y < 0 ? 0 : y;
   }
}


2. Objectlevensduur

U weet al dat objecten worden gemaakt met behulp van de newoperator, maar hoe worden objecten verwijderd? Ze bestaan ​​niet voor altijd. Daar is niet genoeg geheugen voor.

In veel programmeertalen, zoals C++, is er een speciale deleteoperator voor het verwijderen van objecten. Maar hoe werkt dit in Java?

Op Java is alles een beetje anders geregeld. Java heeft geen delete-operator. Betekent dit dat objecten in Java niet worden verwijderd? Nee, die zijn natuurlijk verwijderd. Anders zouden Java-applicaties snel door hun geheugen heen raken, en zou er geen sprake zijn van programma's die maandenlang ononderbroken draaien.

In Java is het verwijderen van objecten volledig geautomatiseerd. De Java-machine zorgt zelf voor het verwijderen van objecten. Dit proces wordt Garbage Collection genoemd en het mechanisme dat afval verzamelt, wordt de Garbage Collector ( GC ) genoemd.

Dus hoe weet de Java-machine wanneer een object moet worden verwijderd?

De vuilnisman verdeelt alle objecten in "bereikbaar" en "onbereikbaar". Als er ten minste één verwijzing naar een object is, wordt het als bereikbaar beschouwd. Als er geen variabele is die naar een object verwijst, wordt het object als onbereikbaar beschouwd en als afval verklaard, wat betekent dat het kan worden verwijderd.

In Java kunt u geen verwijzing naar een bestaand object maken — u kunt alleen verwijzingen toewijzen die u al heeft. Als we alle verwijzingen naar een object wissen, is het voor altijd verloren.

Circulaire verwijzingen

Die logica klinkt geweldig totdat we een eenvoudig tegenvoorbeeld tegenkomen: stel dat we twee objecten hebben die naar elkaar verwijzen (referenties naar elkaar opslaan). Er zijn geen andere objecten die verwijzingen naar deze objecten opslaan.

Deze objecten zijn niet toegankelijk vanuit de code, maar er wordt nog steeds naar verwezen.

Dit is de reden waarom de vuilnisophaler objecten verdeelt in bereikbaar en onbereikbaar in plaats van "gerefereerd" en "niet-gerefereerd".

Bereikbare objecten

Eerst worden objecten die 100% levend zijn toegevoegd aan de bereikbare lijst. Bijvoorbeeld de huidige thread ( Thread.current()) of de console InputStream ( System.in).

Vervolgens wordt de lijst met bereikbare objecten uitgebreid met objecten waarnaar wordt verwezen door de eerste set bereikbare objecten. Vervolgens wordt het weer uitgebreid om objecten op te nemen waarnaar wordt verwezen door deze vergrote set, enzovoort.

Dat betekent dat als er enkele objecten zijn die alleen naar elkaar verwijzen, maar er geen manier is om ze te bereiken vanaf bereikbare objecten, die objecten als afval worden beschouwd en worden verwijderd.


3. Afvalinzameling

Geheugenfragmentatie

Een ander belangrijk punt met betrekking tot het verwijderen van objecten is geheugenfragmentatie. Als je constant objecten aanmaakt en verwijdert, zal het geheugen al snel zwaar gefragmenteerd zijn: gebieden met bezet geheugen worden afgewisseld met gebieden met onbezet geheugen.

Als gevolg hiervan kunnen we gemakkelijk in een situatie terechtkomen waarin we geen groot object kunnen maken (bijvoorbeeld een array met een miljoen elementen), omdat er niet veel vrij geheugen is. Met andere woorden, er kan vrij geheugen zijn, zelfs veel, maar er is misschien geen groot aaneengesloten blok vrij geheugen

Geheugenoptimalisatie (defragmentatie)

De Java-machine lost dit probleem op een specifieke manier op. Het ziet er ongeveer zo uit:

Het geheugen is verdeeld in twee delen. Alle objecten worden gemaakt (en verwijderd) in slechts de helft van het geheugen. Als het tijd is om de gaten in het geheugen op te ruimen, worden alle objecten in de eerste helft gekopieerd naar de tweede helft. Maar ze worden naast elkaar gekopieerd zodat er geen gaten zijn.

Het proces ziet er ongeveer zo uit:

Stap 1: Na het maken van objecten

Vuilnisophaaldienst op Java

Stap 2: Verschijning van "gaten"

Garbage collection in Java 2

Stap 3: Eliminatie van "gaten"

Garbage collection in Java 3

En daarom hoef je geen objecten te verwijderen. De Java-machine kopieert gewoon alle bereikbare objecten naar een nieuwe locatie en maakt het hele geheugengebied vrij waar de objecten vroeger waren opgeslagen.