1. Xususiyatlar: getter va setter
Katta loyiha ustida bir vaqtda o'nlab dasturchilar ishlaganda, ko'pincha ular sinf maydonlarida saqlanadigan ma'lumotlarga turlicha munosabatda bo'lishlari sababli muammolar yuzaga keladi.
Hech kim sinflarning hujjatlarini batafsil o'rganmaydi yoki unda barcha holatlar tasvirlanmagan bo'lishi mumkin, shuning uchun obyekt ichidagi ma'lumotlar "buzilishi" va obyekt yaroqsiz bo'lib qolishi mumkin bo'lgan vaziyatlar tez-tez yuzaga kelishi mumkin.
Bunday vaziyatlardan qochish uchun, Java da sinf maydonlarining barchasi private qilinadi. Faqatgina sinf usullari sinf o'zgaruvchilarini o'zgartira oladi va boshqa sinflarning hech qanday usullari to'g'ridan-to'g'ri sinf o'zgaruvchilariga kira olmaydi. Mana shunday.
Agar boshqa sinflar sizning sinfingiz ichidagi ma'lumotlarni olish yoki o'zgartirishni xohlasalar, sinf kodiga ikkita get-usuli va set-usuli qo'shishingiz kerak bo'ladi. Misol:
| Kod | Izoh |
|---|---|
|
private-maydon nameMaydonni konstruktor orqali initsializatsiya qilish getName()— usul name maydonining qiymatini qaytaradisetName()— usul name maydonining qiymatini o'zgartiradi |
Hech qanday boshqa sinf name maydonining qiymatini to'g'ridan-to'g'ri o'zgartira olmaydi. Agar kimga name maydonining qiymatini olish kerak bo'lsa, u getName() usulini type Person obyektida chaqirishi kerak bo'ladi. Agar qandaydir kod name maydonining qiymatini o'zgartirmoqchi bo'lsa, u setName() usulini type Person obyektida chaqirishi kerak bo'ladi.
getName() usuli hali ham name maydonining getteri deb ataladi, va setName() usuli - name maydonining setteri deb ataladi.
Bu juda keng tarqalgan yondashuv. Java kodining 80-90% da siz hech qachon sinfning ochiq o'zgaruvchilarini ko'rmaysiz. Buning o'rniga ular private (yoki protected) deb e'lon qilinadi va har bir o'zgaruvchi ochiq getteri va setteri mavjud bo'ladi.
Bu yondashuv kodni uzunroq qiladi, lekin ishonchliroq.
Sinf o'zgaruvchisiga to'g'ridan-to'g'ri murojaat qilish — bu ikki chiziqli aylanma yo'l: osonroq va tezroq, lekin agar barchamiz shunday qilsak, barchaga yomon bo'ladi.
Faraz qilaylik, siz x va y tekislikda nuqtani tavsiflovchi sinf yaratmoqchisiz. Yangi dasturchi buni qanday qilgan bo'lishi mumkin:
class Point
{
public int x;
public int y;
}
Va tajribali Java-dasturchi buni qanday qilgan bo'lishi mumkin:
| Kod |
|---|
|
Kod uzunroq bo'ldimi? Albatta.
Lekin setter va getterlarda parametrlarni tekshirishingiz mumkin. Masalan, x va y har doim nolga teng yoki undan katta bo'lishini tekshirish mumkin. Misol:
| Kod | Izoh |
|---|---|
|
2. Obyektning hayot davomiyligi
Siz allaqachon obyektlar new operatori yordamida yaratilishini bilasiz, lekin obyektlar qanday olib tashlanadi? Ular abadiy qolavermaydilar — bunga hech qanday xotira yetarli bo'lmaydi.
C++ kabi ko'plab dasturlash tillarida obyektni olib tashlash uchun maxsus delete operatori mavjud. Java da bu qanday tashkil etilgan?
Java da hammasi biroz boshqacha, va Java da delete operatori mavjud emas. Bu Java da obyektlar o'chirilmaydi, degani emasmi? Yo'q, albatta olib tashlanadi. Aks holda Java ilovalarda xotira tezda tugardi va bir nechta oy uzluksiz ishlash haqida gap ham bo'lmas edi.
Java da obyektlarni o'chirish jarayoni to'liq avtomatlashtirilgan – obyektlarni olib tashlash bilan Java-mashina o'zi shug'ullanadi. Bu jarayon axlat yig'ish (garbage collecting) deb ataladi, va axlat yig'uvchi mexanizm — axlat yig'uvchi — Garbage Collector yoki qisqacha GC.
Java-mashina qanday qilib biron bir ob'ektni olib tashlash kerakligini va qachon olib tashlash kerakligini bilib olishi mumkin?
Hammasini axlat yig'uvchisi ob'ektlarni ikki guruhga ajratadi: erishiladigan va erishilmaydigan. Agar ob'ektga hech bo'lmaganda bitta ishora mavjud bo'lsa, u erishiladigan hisoblanadi. Agar hech qanday o'zgaruvchi ob'ektga ishora qilmasa, bunday ob'ekt erishilmaydigan hisoblanadi va axlat deb e'lon qilinadi: ya'ni uni olib tashlash mumkin.
Java da mavjud bo'lgan obyektga ishora olish mumkin emas: faqat tashqaridan berilgan ishora qo'yish mumkin. Agar biz obyektga barcha ishoralarni o'chirsak, u abadiy yo'qoladi.
Tsiklik ishoralar
Oldingi mantiq ajoyib eshitiladi, to biz sodda qarshi misolni o'ylab topmagunimizcha: bizda bir-biriga ishora qiladigan ikkita ob'ekt mavjud (bir-biriga ishoralarni saqlash). Boshqa hech kim bu ob'ektlarga hech qanday ishoralarni saqlamaydi.
Bu obyektlarga qolgan koddan murojaat qilish mumkin emas, lekin ularga hali ham ishoralar mavjud.
Shuning uchun axlat yig'uvchi ob'ektlarni «ishoralar bilan ob'ektlar» va «ishoralarsiz ob'ektlar» emas, balki erishiladigan va erishilmaydigan ob'ektlarga ajratadi.
Erishiladigan obyektlar
Birinchi navbatda erishiladigan ro'yxatga 100% tirik deb hisoblanadigan ob'ektlar qo'shiladi. Masalan, mavjud ip (Thread.current()) yoki Konsol (System.in).
Keyin birinchi erishiladigan ob'ektlarga ishora qiladiganlar erishiladigan ob'ektlar ro'yxatini to'ldiradi. So'ngra ikkinchilar, va hokazo.
Bu usul bilan faqat bir-biriga ishora qiladigan ob'ektlar guruhi mavjud bo'lsa, lekin erishiladigan ob'ektlar orasiga kirish imkonsiz bo'lsa, bunday ob'ektlar axlat deb hisoblanadi va olib tashlanadi.
3. Axlat yig'ish
Xotira fragmentatsiyasi
Obyektlarni olib tashlash bilan bog'liq yana bir muhim nuqta — xotira fragmentatsiyasi. Agar siz doimiy ravishda obyektlar yaratib, olib tashlasangiz, tez orada barcha xotira aralash bo'lib ketadi: band xotira joylari va bo'sh joylar aralashib ketadi.
Va osonlikcha shunday vaziyat yuzaga kelishi mumkin, biz katta ob'yektni (masalan, millionta elementli massiv) yaratolmaymiz, chunki yirik bo'sh xotira joyi yo'q. T.e. bo'sh xotira bor, va ko'p, lekin katta va yaxlit bo'sh xotira joyidan bo'lmasligi mumkin.
Xotira optimallashtirish (defragmentatsiya)
Java-mashina bu muammoni o'ziga xos tarzda hal qiladi. Bu taxminan quyidagicha ko'rinadi:
Xotira ikki qismga bo'linadi. Barcha ob'yektlar faqat bir qismida yaratiladi (va olib tashlanadi). Xotirada teshiklarni olib tashlash vaqti kelganda, birinchi yarim qismdagi barcha ob'ektlar ikkinchi yarim qismga ko'chiriladi. Lekin ob'ektlar bir-biriga yaqin qilib, teshiklar yo'qdek qilib ko'chiriladi.
Bu jarayon taxminan quyidagicha ko'rinadi:
Birinchi bosqich: obyektlar yaratilgandan keyin

Ikkinchi bosqich: «teshiklar» paydo bo'lishi

Uchinchi bosqich: «teshiklar»ni bartaraf etish

Shunday qilib, ob'yektlarni o'chirish shart emas. Java-mashina barcha erishiladigan ob'ektlarni yangi joyga ko'chiradi, va eski ob'ektlar saqlangan xotira maydonini bo'sh deb e'lon qiladi.
GO TO FULL VERSION