1. Properties: getter at setter

Kapag ang isang malaking proyekto ay binuo ng dose-dosenang mga programmer sa parehong oras, ang mga problema ay madalas na lumalabas kung iba ang kanilang pangangasiwa sa data na nakaimbak sa mga field ng klase.

Marahil ay nabigo ang mga tao na pag-aralan nang detalyado ang dokumentasyon ng klase, o marahil ay hindi nito inilalarawan ang bawat kaso. Bilang resulta, may mga madalas na sitwasyon kapag ang panloob na data ng isang bagay ay maaaring maging "nasira", na ginagawang hindi wasto ang bagay.

Upang maiwasan ang mga sitwasyong ito, kaugalian na gawing pribado ang lahat ng field ng klase sa Java . Tanging ang mga pamamaraan ng klase ang maaaring magbago ng mga variable ng klase. Walang mga pamamaraan mula sa ibang mga klase ang maaaring direktang ma-access ang mga variable.

Kung gusto mong makuha o baguhin ng ibang mga klase ang data sa loob ng mga object ng iyong klase, kailangan mong magdagdag ng dalawang pamamaraan sa iyong klase — isang get method at isang set method. Halimbawa:

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


privatename field



Initialization ng field sa pamamagitan ng constructor


getName()— Ibinabalik ng paraang ito ang value ng name field




setName()— Binabago ng pamamaraang ito ang value ng name field

Walang ibang klase ang maaaring direktang baguhin ang halaga ng field ng pangalan. Kung kailangan ng isang tao na makuha ang halaga ng field ng pangalan, kakailanganin nilang tawagan ang getName() pamamaraan sa isang Personbagay. Kung gustong baguhin ng ilang code ang halaga ng field ng pangalan, kakailanganin nitong tawagan ang setName() pamamaraan sa isang Personbagay.

Ang getName()pamamaraan ay tinatawag ding " getter para sa field ng pangalan", at ang setName()pamamaraan ay tinatawag na " setter para sa field ng pangalan ".

Ito ay isang napaka-karaniwang diskarte. Sa 80-90% ng lahat ng Java code, hindi ka na makakakita ng mga pampublikong variable sa isang klase. Sa halip, idedeklara ang mga ito private(o protected), at ang bawat variable ay magkakaroon ng mga pampublikong getter at setter.

Ang diskarte na ito ay ginagawang mas mahaba ang code, ngunit mas maaasahan.

Ang direktang pag-access sa isang variable ng klase ay tulad ng pagliko ng iyong sasakyan sa pamamagitan ng dobleng dilaw na linya : mas madali at mas mabilis ito, ngunit kung gagawin ito ng lahat, lalala ang mga bagay para sa lahat.

Sabihin nating gusto mong lumikha ng isang klase na naglalarawan ng isang punto ( x, y). Narito kung paano ito gagawin ng isang baguhang programmer:

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

Narito kung paano ito gagawin ng isang bihasang Java programmer:

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

Mas mahaba ba ang code? Walang alinlangan.

Ngunit maaari kang magdagdag ng pagpapatunay ng parameter sa mga getter at setter. Halimbawa, maaari mong tiyakin na xat ypalaging mas malaki kaysa sa zero (o hindi bababa sa zero). Halimbawa:

Code Tandaan
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. Panghabambuhay ng bagay

Alam mo na na ang mga bagay ay nilikha gamit ang newoperator, ngunit paano tinatanggal ang mga bagay? Hindi sila umiiral magpakailanman. Walang sapat na memorya para doon.

Sa maraming mga programming language, tulad ng C++, mayroong isang espesyal deletena operator para sa pagtanggal ng mga bagay. Ngunit paano ito gumagana sa Java?

Sa Java, ang lahat ay nakaayos nang medyo naiiba. Walang delete operator ang Java. Nangangahulugan ba ito na ang mga bagay ay hindi tinanggal sa Java? Hindi, sila ay tinanggal, siyempre. Kung hindi, ang mga application ng Java ay mabilis na mauubusan ng memorya, at walang pag-uusapan tungkol sa mga program na tumatakbo nang walang pagkaantala sa loob ng maraming buwan.

Sa Java, ang pagtanggal ng mga bagay ay ganap na awtomatiko. Ang Java machine mismo ang humahawak sa pagtanggal ng mga bagay. Ang prosesong ito ay tinatawag na pangongolekta ng basura, at ang mekanismo na nangongolekta ng basura ay tinatawag na garbage collector ( GC ).

Kaya paano malalaman ng Java machine kung kailan tanggalin ang isang bagay?

Hinahati ng basurero ang lahat ng bagay sa "reachable" at "unreachable". Kung mayroong kahit isang reference sa isang bagay, ito ay itinuturing na maaabot. Kung walang variable na tumutukoy sa isang bagay, ang bagay ay itinuturing na hindi maabot at idineklara itong basura, na nangangahulugang maaari itong tanggalin.

Sa Java, hindi ka makakagawa ng reference sa isang umiiral na object — maaari ka lang magtalaga ng mga reference na mayroon ka na. Kung burahin natin ang lahat ng mga sanggunian sa isang bagay, mawawala ito magpakailanman.

Mga pabilog na sanggunian

Napakaganda ng lohika na iyon hanggang sa makarating tayo sa isang simpleng counterexample: ipagpalagay na mayroon tayong dalawang bagay na tumutukoy sa isa't isa (nag-imbak ng mga sanggunian sa isa't isa). Walang ibang mga bagay na nag-iimbak ng mga sanggunian sa mga bagay na ito.

Ang mga bagay na ito ay hindi ma-access mula sa code, ngunit sila ay isinangguni pa rin.

Ito ang dahilan kung bakit hinahati ng tagakolekta ng basura ang mga bagay sa maabot at hindi maabot sa halip na "na-reference" at "hindi naka-reference".

Mga bagay na naaabot

Una, ang mga bagay na 100% buhay ay idinaragdag sa maaabot na listahan. Halimbawa, ang kasalukuyang thread ( Thread.current()) o ang console InputStream ( System.in).

Pagkatapos ay lumalawak ang listahan ng mga naaabot na bagay upang isama ang mga bagay na nire-reference ng unang hanay ng mga naaabot na bagay. Pagkatapos ay pinalawak itong muli upang isama ang mga bagay na tinutukoy ng pinalaki na set na ito, at iba pa.

Nangangahulugan iyon na kung mayroong ilang mga bagay na tumutukoy lamang sa isa't isa, ngunit walang paraan upang maabot ang mga ito mula sa mga naaabot na bagay, ang mga bagay na iyon ay ituturing na basura at tatanggalin.


3. Pagkolekta ng basura

Pagkapira-piraso ng memorya

Ang isa pang mahalagang punto na nauugnay sa pagtanggal ng bagay ay ang pagkapira-piraso ng memorya. Kung patuloy kang lumikha at magde-delete ng mga bagay, sa lalong madaling panahon ang memorya ay mabibigat na pira-piraso: ang mga lugar ng sinasakop na memorya ay sasalungat sa mga lugar ng hindi sinasakop na memorya.

Bilang resulta, madali tayong mapunta sa isang sitwasyon kung saan hindi tayo makakalikha ng isang malaking bagay (halimbawa, isang array na may isang milyong elemento), dahil walang malaking tipak ng libreng memorya. Sa madaling salita, maaaring mayroong libreng memorya, kahit na marami nito, ngunit maaaring walang malaking magkadikit na bloke ng libreng memorya.

Pag-optimize ng memorya (defragmentation)

Ang Java machine ay malulutas ang problemang ito sa isang tiyak na paraan. Mukhang ganito:

Ang memorya ay nahahati sa dalawang bahagi. Ang lahat ng mga bagay ay nilikha (at tinanggal) sa isang kalahati lamang ng memorya. Pagdating ng oras upang linisin ang mga butas sa memorya, ang lahat ng mga bagay sa unang kalahati ay kinopya sa ikalawang kalahati. Ngunit sila ay kinopya sa tabi ng bawat isa upang walang mga butas.

Ang proseso ay halos ganito:

Hakbang 1: Pagkatapos gumawa ng mga bagay

Pagkolekta ng basura sa Java

Hakbang 2: Hitsura ng "mga butas"

Pagkolekta ng basura sa Java 2

Hakbang 3: Pag-aalis ng "mga butas"

Pagkolekta ng basura sa Java 3

At iyon ang dahilan kung bakit hindi mo kailangang tanggalin ang mga bagay. Kinokopya lang ng Java machine ang lahat ng naaabot na bagay sa isang bagong lokasyon, at pinapalaya ang buong lugar ng memorya kung saan naka-imbak ang mga bagay.