1. Referanslı Dəyişənlər
Java dilində dəyişənlər iki növ ola bilər: primitiv tip dəyişənləri və digərləri. İndi isə o "digərləri" haqqında danışacağıq.
Əslində düzgün ifadə etmək üçün deməliyik ki, burada primitiv tip dəyişənləri (primitive type variables) və referanslı dəyişənlər (reference variables) var. Bəs bu referanslı dəyişənlər nə deməkdir?
Primitiv tiplərdən fərqli olaraq, hansılar ki, dəyərləri birbaşa dəyişən daxilində saxlayır, referanslı tiplər obyektlərə referansları saxlayır. Yəni, yaddaşda haradasa bir obyekt var, və referanslı dəyişəndə sadəcə həmin obyektin yaddaşdakı ünvanı saxlanılır (referans).
Dəyərlər birbaşa dəyişənin içində yalnız primitiv tiplər tərəfindən saxlanılır, bütün digər tiplər isə yalnız obyektə olan referansı saxlayır. Əvvəllər artıq iki belə dəyişən tipi ilə tanış olmuşdunuz — bunlar String
tipli dəyişənlər və massiv tipli dəyişənlərdir.
Həm massiv, həm də sətir yaddaşda haradasa saxlanılan obyektlərdir. String
tipli dəyişənlər və massiv tipli dəyişənlər yalnız obyektlərə referansları saxlayır.
int a, int b və double d
dəyişənləri — primitivdir və dəyəri öz daxilində saxlayır.
String str
dəyişəni — referanslıdır və yaddaşda String
tipli obyektin ünvanını (referansı) saxlayır.
Primitiv dəyəri primitiv tipli dəyişənə təyin edəndə, dəyər köçürülür (kopyalanır). Amma referanslı dəyişənlərdə yalnız obyektin ünvanı köçürülür, amma obyektin özü kopyalanmır.
2. İstinadların mahiyyəti
İstinad dəyişənləri ilə primitiv dəyişənlər arasında prinsipial fərq nədir?
Primitiv dəyişən bir qutu kimidir: orada hansısa bir dəyəri saxlamaq olar. İstinad dəyişəni daha çox üzərində telefon nömrəsi yazılmış bir kağıza bənzəyir.
Avtomobil vs avtomobilin açarları
Təsəvvür edin ki, dostunuza ad günündə avtomobil bağışlamaq qərarına gəlmisiniz. Siz avtomobili qutuya qoyub özünüzlə apara bilməzsiniz: avtomobil bunun üçün çox böyükdür.
Daha rahat yol avtomobilin açarlarını və onları saxlayacaq kifayət qədər böyük bir qutu götürməkdir. Dostunuz qutudan açarları çıxaranda artıq hər şeyi başa düşəcək. Bütün avtomobili özünüzlə götürmək əvəzinə sadəcə açarları vermək kifayətdir.
İnsan vs onun telefon nömrəsi
Və ya başqa bir variant: insan və onun telefon nömrəsi. Telefon nömrəsi insanın özü deyil, amma telefon nömrəsindən ona zəng etmək, ondan məlumat almaq, əmrlər vermək üçün istifadə etmək olar.
İstinad da obyektlə qarşılıqlı əlaqə üçün istifadə olunur. Bütün obyektlər bir-biri ilə istinadlar vasitəsi ilə qarşılıqlı əlaqədədir. «İnsanları mübadilə etmək» əvəzinə, sadəcə telefon nömrələrini mübadilə etmək kifayətdir.
Primitiv dəyişənə dəyər təyin etdikdə, onun dəyəri kopyalanır (dublikat edilir). Amma istinad dəyişənə dəyər təyin etdikdə, yalnız obyektin ünvanı («telefon nömrəsi») kopyalanır, obyektin özü isə kopyalanmır.
İstinad əlavə bir üstünlük verir: obyektə istinad bir metoda ötürülə bilər və bu metod həmin obyektin üzərində dəyişikliklər edə bilər, istinadı istifadə edərək obyektin metodlarını çağıra və obyektin içindəki məlumatlara müraciət edə bilər.
3. Referansları Təyinetmə
Referans dəyişənlərini təyin edəndə sadəcə obyektin yaddaş ünvanını təyin edirik. Obyektlərin özləri isə yaranmır və ya yox olmur.
Bu yanaşma böyük həcmli yaddaşın kopyalanmasından yayınmağa imkan verir. Əgər nəhəng bir obyekti hansısa metoda ötürmək lazım olsa, sadəcə obyektə referansı ötürmək kifayətdir. Referans daha az yer tutur.
Bütün referans dəyişənlərinin ölçüsü (tipdən asılı olmayaraq) eynidir və 4 bayt təşkil edir (int tipi kimi). Amma! Əgər tətbiqiniz 64-bitlik Java virtual maşında işə salınıbsa, bütün referansların ölçüsü 8 bayt (64 bit) olacaq.
Referansları sadəcə bir-birinə təyin etmək olar. Siz referansları dəyişdirə və ya onlara təsadüfi dəyərlər təyin edə bilməzsiniz:
Kod | Təsvir |
---|---|
|
Bu mümkündür |
|
Amma bu — mümkün deyil |
|
Və bu da — mümkün deyil |
4. Boş istinad — null
Bəs istinad dəyişəni nə saxlayır, əgər ona hələ bir şey təyin edilməyibsə?
O, boş bir istinad saxlayır — null. null
— bu, Java-da xüsusi bir açar sözdür, yəni istinadın olmamasını (boş istinadı) göstərir. null
dəyəri istənilən istinad dəyişəninə təyin edilə bilər.
Bütün istinad dəyişənləri, əgər onlara hər hansısa bir istinad təyin edilməyibsə, null
dəyərə malikdirlər.
Nümunələr:
Kod | Təsvir |
---|---|
|
Dəyişən String name ilkin olaraq bu dəyərə sahibdir: null .Dəyişən int age ilkin olaraq bu dəyərə sahibdir: 0 . |
Əgər lokal dəyişənlərə heç bir dəyər təyin edilməyibsə, onlar ilkin olaraq həm primitiv tiplər, həm də istinad tipləri üçün uninicializasiya olunmuş sayılırlar.
Əgər dəyişən hansısa obyektə istinad edirsə və siz dəyişən dəyərini silmək istəyirsinizsə, sadəcə ona null
istinadını təyin edin.
Kod | Təsvir |
---|---|
|
s boş istinad null saxlayır.s obyekt-sətirə istinad saxlayırs boş istinad null saxlayır |
5. Metodlara istinadların ötürülməsi
Əgər hansısa metodun istinad dəyişənləri olan parametrləri varsa, onlara dəyərlər ötürülməsi adi dəyişənlərlə işləyən kimi həyata keçirilir. Sadəcə parametr dəyişəninə başqa bir dəyişənin dəyəri təyin edilir.
Nümunə:
Kod | Təsvir |
---|---|
|
Metod fill təyin edilmiş array massivini verilmiş value dəyəri ilə doldurur. |
fill
metodu çağırıldıqda array
dəyişəninə data
massivinə istinad edən link təyin edilir. value
dəyişəninə isə "Salam"
obyekt-şəklində string istinad təyin edilir.
Yaddaşda vəziyyət metod çağırılmadan əvvəl belə görünəcək:
Metodun işlək vəziyyətdə olduğu zaman belə görünəcək:

data
və array
dəyişənləri yaddaşda eyni massiv konteynerinə istinad edir (link saxlayır).
value
dəyişəni Salam
string obyektinə istinad edir.
Massivin hüceyrələri də sadəcə Salam
obyektinə istinad edir.
Əslində heç bir obyektin təkrarlanması baş vermir — yalnızca istinadlar kopyalanır.
6. C/C++ dili ilə müqayisə
Bəzən Java proqramçılarına müsahibədə belə sual verirlər: Java-da məlumatlar metodlara necə ötürülür? Bəzən dəqiqləşdirilir: istinadla yoxsa qiymətlə ötürülür?
Bu sual C++ dilindən gəlir — Java dilində onun heç bir mənası yoxdur. Java-da dəyişən-parametrlərə həmişə sadəcə dəyişən-argümentlərin qiymətləri təyin edilir. Beləliklə doğru cavab — qiymətlə.
Ancaq hazır olun ki, mövqeyinizi izah edəsiniz, çünki sizə dərhal etiraz edə bilərlər, deyə bilərlər ki, «primitiv tiplər qiymətlə ötürülür, istinadlar isə istinadla».
Bu problemin kökləri ilə əlaqəlidir ki, çoxlu Java proqramçıları keçmişdə C++ proqramçıları olublar. Orada isə «parametrlər metodlara necə ötürülür» sualı çox mühüm rol oynayırdı.
Java-da hər şey birmənalıdır: primitiv tiplər qiymətləri saxlayır, istinadlar da qiymət saxlayır — istinadı. Bütün məsələ ondadır ki, dəyişənin qiymətini nə hesab etmək lazımdır.
C++ dilində dəyişəndə həm obyektə istinad, həm də obyektin özü saxlanıla bilərdi. Eyni şey primitiv tiplərə də aid idi: dəyişəndə qiymət saxlamaq və ya dəyişəni int
tipinə istinad kimi elan etmək olardı. Buna görə qarışmamaq üçün C++ proqramçıları obyektə istinadı həmişə istinad adlandırırdılar, obyektin özünü isə qiymət.
C++-da belə vəziyyət asanlıqla yarana bilərdi ki, bir dəyişən obyektin özünü, başqa bir dəyişən isə həmin obyektə istinad saxlayırdı. Buna görə də dəyişənin özündə nə saxlandığı — obyektin özü, yoxsa yalnız istinad olub-olmadığı məsələsi çox mühüm idi. Metodlara obyekt ötürərkən o kopyalanırdı (əgər qiymətlə ötürülürdüsə) və kopyalanmırdı (əgər istinadla ötürülürdüsə).
Java-da bu ikililik yoxdur və doğru cavab belə səslənir: Java-da metodlara parametrlər qiymətlə ötürülür. Sadəcə istinad dəyişənləri vəziyyətində bu qiymət — istinaddır.
GO TO FULL VERSION