Select Page

Ako Java pracuje s pamäťou pri referenčných typoch

Jaroslav Beňo

17/05/2020

Referenčným dátovým typom sú všetky typy, ktoré nie sú primitívnymi dátovými typmi. Objekty, ktoré vznikli na základe triedy sú referenčné dátové typy. Objekty vznikajú ak zavoláme kľúčové slovo new pri konštruktore alebo keď vytvárame String pomocou úvodzoviek. V tomto článku sa dozvieš ako Java pracuje s pamäťou pri referenčných typoch.

Napríklad ak máme triedu Dog a na základe tejto triedy vznikne objekt Dog, tak tento objekt sa vytvorí do pamäte. Do premennej, ktorá má uchovávať tento objekt Dog sa neuloží priamo objekt Dog, ale iba jeho odkaz (referencia, adresa) na miesto kde v pamäti sa nachádza.

Príklad

Dog dog = new Dog();

Čo sa stalo? V halde sa vytvoril nový objekt typu Dog a jeho adresa sa uložila do premennej dog.

Ak by som vytvoril novú premennú napríklad dog2 a do nej by som priradil dog, čo sa stane?

Dog dog2 = dog;

Stane sa to, že do dog2 sa uloží to, čo je v dog. Čo je teraz v dog? Je tam adresa na ten prvý vytvorený objekt.

01 ulozenie objektu do pamate

Inak povedané premenná dog ukazuje na novo vytvorený objekt typu Dog v pamäti a potom aj dog2 ukazuje na ten istý objekt.

Krajšie by to bolo ak by sme použili String. Tak skúsme znovu ale trošku si to spravíme zložitejšie.

String name = "Jaro";
String surename = "Beno";
name = "Fero";
surename = name;

V prvom kroku sa vytvorí objekt Jaro a jeho adresa sa priradí (uloží do premennej name).

02 praca s pamatou

V druhom kroku sa vytvorí objekt Beno a jeho adresa sa uloží do premennej surename.

03 praca s pamatou

V treťom kroku sa vytvorí objekt typu String s hodnotou Fero a jeho adresa sa uloží do premennej name. Premenná name má v sebe uloženú adresu na Fero. Teda predchádzajúca hodnota, čo bola adresa na objekt Jaro sa zmazala a nahradila adresou na objekt Fero. Tým pádom, žiadna premenná už neukazuje na objekt Jaro. Tento objekt teda už nie je viac použiteľný v našom programe. Teraz „visí“ v pamäti. Java sama spúšťa takzvaný garbage collector (zberač smetí), ktorým z pamäti uvoľňuje presne takéto objekty, na ktoré už v programe neexistuje referencia – žiadna premenná v programe neukazuje na tento objekt.

04 praca s pamatou

V kroku číslo 4 do premennej surename priraďujeme tú hodnotu, ktorá sa nachádza v premennej name a tou hodnotou je adresa na objekt Fero.

05 praca s pamatou

Teraz obidve premenné ukazujú na ten istý objekt alebo inak povedané obidve premenné uchovávajú adresu na objekt typu String s hodnotou Fero. Objekty Jaro a Beno sa potom vymažú z pamäte automaticky.

Čo to všetko pre nás znamená? Prečo sa tomu tak venujeme?

Je to preto, aby sme si rozmysleli kde posuniem adresu na objekt a čo sa môže stať.  Čo ak posuniem premennú name do metódy? Čo sa môže stať? Nemusí sa stať nič, ale môže sa stať to, že v metóde sa tam súčasný objekt môže zmeniť.

Príklad:

Dog dog3 = new Dog("T-REX");
System.out.println(dog3.getName());

Vytvoríme si psa s menom T-REX. Vytvoril sa v pamäti. Jeho adresa sa uložila do premennej dog3. Teraz vypíšem jeho meno na konzolu. Na konzole sa objaví T-REX.

Dog dog3 = new Dog("T-REX");
System.out.println(dog3.name);
workWithDog(dog3);
System.out.println(dog3.name);

Teraz som zavolal metódu workWithDog a do nej som vložil dog3. Čo som spravil? Spravil som to, že hodnotu z dog3 som posunul do vnútra metódy. Teda som tam posunul adresu. Ak by som pracoval s primitívnym typom, tak by som do vnútra metódy posunul hodnotu. Teraz som posunul adresu.

Pozrime sa na metódu:

static void workWithDog(Dog dog){
    dog.name = "Rex";
}

V metóde sa objektu dog mení meno na Rex. Čo sa stane?

06 praca s pamatou
Dog dog3 = new Dog("T-REX");
System.out.println(dog3.name);
workWithDog(dog3);
System.out.println(dog3.name);

Výpis tohto kódu bude nasledovný: najprv sa vypíše T-REX a potom Rex. V tomto príklade vypisujem meno objektu dog3. Raz je T-REX a po zavolaní metódy sa zmenil na Rex. Ak by sme niečo podobné chceli spraviť s primitívnym typom, tak vonkajšia premenná sa nám nezmení.

int num = 41;
System.out.println(num);
workWithInt(num);
System.out.println(num);

Výstup na konzole bude dvakrát vypísané číslo 41.

Najnovšie články

O autorovi: Jaroslav Beňo

Jaro je v skratke kresťan, manžel, otec a programátor. Na tomto webe sa venuje programovaniu. Jeho túžbou je šíriť vedomosti ďalej, aby sme mohli spolu rásť.

Pripravil viacero online video kurzov. Jeho sociálne siete:

Podobné články

Písanie kódu – programovanie v Jave

Ak budeš písať kód / programovať v jazyku Java, tak budeš používať text. Áno je to tak, programy budeme písať vo forme textu – nečudo, keď hovoríme o písaní. Kód by sme mohli začať písať do jednoduché textového editoru (program v tvojom počítači). Vo windowse máš...

Programovací jazyk Java – plán štúdia

Rozhodol si sa študovať programovací jazyk Java, alebo o tom uvažuješ. Pozeral si si pracovné ponuky pre Java programátora, alebo si našiel zložitejší návod ako napísať Java web aplikáciu. Natrafil si na veľké množstvo pojmov, ktorým nerozumieš. Máš v tom...

Share This

Páčil sa ti článok? Zváž zdieľanie. Ďakujeme.