1. Referenciaváltozók

A Java nyelvben kétféle változó létezik: primitív változók és minden más. Ahogy megtörténik, most "minden másról" fogunk beszélni.

Valójában helyesebb lenne azt mondani, hogy vannak primitív változók és referenciaváltozók . Tehát mik ezek a referenciaváltozók?

A primitív típusokkal ellentétben, amelyek változói közvetlenül tárolják az értékeket, a referenciaváltozók az objektumokra való hivatkozásokat tárolják. Vagyis van egy objektum valahol a memóriában, és a referenciaváltozó egyszerűen eltárolja ennek az objektumnak a címét a memóriában (hivatkozás az objektumra).

Csak a primitív típusok tárolnak értékeket közvetlenül a változókon belül. Minden más típus csak egy objektumhivatkozást tárol . Mellesleg, már találkozott két ilyen típusú változóval – Stringváltozókkal és tömbváltozókkal .

A tömb és a karakterlánc is valahol a memóriában tárolt objektumok. Stringa változók és a tömbváltozók csak az objektumokra való hivatkozásokat tárolják.

Hivatkozási változók Java nyelven

int a, int b and double dprimitív változók, amelyek értékeiket magukban tárolják.

A String strváltozó egy hivatkozás, és a Stringmemóriában tárolja egy objektum címét (hivatkozását).

Amikor egy primitív típusú változóhoz primitív értéket adunk, annak értéke másolódik (duplikálódik). Referenciaváltozó hozzárendelésekor csak az objektum címe kerül másolásramaga az objektum nem kerül másolásra .


2. Miről szólnak a referenciák?

Mi az alapvető különbség a referenciaváltozók és a primitív változók között?

A primitív változó olyan, mint egy doboz: tárolhatunk benne valamilyen értéket. A referenciaváltozó inkább egy papírdarab, amelyen telefonszám található.

Egy autó kontra kulcs az autóhoz

Képzeld el, hogy úgy döntesz, hogy a barátodnak autót adsz születésnapjára. Nem fogod dobozba csomagolni és magaddal vinni: az autó túl nagy ahhoz.

Sokkal kényelmesebb csak az autókulcsokat egy akkora dobozban elhelyezni, hogy elférjen benne. Barátod mindent megért majd, amikor kiveszi a kulcsokat a dobozból. Nem kell az egész autót magával vinnie, ha egyszerűen átadhatja a kulcsokat.

Egy személy vs a telefonszáma

Vagy itt egy másik összehasonlítás: egy személy és a telefonszáma. A telefonszám nem a személy, de egy telefonszám segítségével felhívhatja, információt kérhet tőle, vagy utasításokat adhat.

Hasonlóképpen egy hivatkozást használnak az objektumokkal való interakcióhoz. Minden objektum kölcsönhatásba lép egymással hivatkozások segítségével. Ahelyett, hogy "embert cserélnénk", egyszerűen telefonszámot cserélünk.

Amikor értéket adunk egy primitív változóhoz, az értéke másolódik (duplikálódik). Amikor egy referenciaváltozóhoz értéket rendelünk, csak az objektum címét (telefonszámát) másolja át – magát az objektumot nem másolja át.

A hivatkozás még egy előnyt kínál: átadhat egy objektumhivatkozást valamilyen metódusnak, és a metódus képes lesz módosítani (megváltoztatni) az objektumot a rá való hivatkozás használatával, metódusainak meghívásával és az objektumon belüli adatok elérésével.


3. Referenciák hozzárendelése

A referenciaváltozók hozzárendelésekor csak az objektum memóriában lévő címe kerül hozzárendelésre. Maguk a tárgyak nem jelennek meg és nem tűnnek el.

Ezzel a megközelítéssel elkerülhető a nagy mennyiségű memória másolása. Ha nagyon nagy objektumot kell átadni egy metódusnak, akkor csak átadjuk az objektumhivatkozást, és kész. A hivatkozás sokkal kevesebb helyet foglal el.

Referenciák hozzárendelése

Az összes referenciaváltozó mérete (típusuktól függetlenül) azonos – 4 bájt (mint egy int). De! Ha az alkalmazás 64 bites Java gépen fut, akkor az összes hivatkozás 8 bájt (64 bit) méretű lesz.

Ráadásul a referenciák csak egymáshoz rendelhetők. Nem módosíthatja a hivatkozásokat, és nem rendelhet tetszőleges értéket a referenciaváltozókhoz:

Kód Leírás
String hello = "Hello";
String s = hello;
Ez megengedett
String hello = "Hello";
hello++;
De ez nem megengedett
String hello = 0x1234;
Ez pedig nem megengedett

4. nullReferencia

És mit tárol egy referenciaváltozó, ha még nincs hozzárendelve semmi?

Null hivatkozást tárol . nullegy speciális Java kulcsszó, ami a hivatkozás hiányát jelenti (üres hivatkozás). Az nullérték bármely referenciaváltozóhoz hozzárendelhető.

Minden referenciaváltozó, nullhacsak nincs hozzájuk rendelve valamilyen hivatkozás.

Példák:

Kód Leírás
class Person
{
   public static String name;
   public static int age;
}


A String nameváltozó alapértelmezett értéke: null.
A int ageváltozó alapértelmezett értéke: 0.

Azok a helyi változók, amelyekhez nem rendeltek értéket, mind a primitív, mind a referenciatípusok esetében inicializálatlannak minősülnek.

Ha egy változó valamilyen objektumra való hivatkozást tárol, és törölni szeretné a változó értékét, akkor csak nulla hivatkozást rendeljen hozzá.

Kód Leírás
String s = null;
s = "Hello";
s = null;
süzletek null.
shivatkozást tárol egy karakterlánc objektum
stárolja null.

5. Hivatkozások átadása a módszerekre

Ha egy metódus referencia típusú paraméterekkel rendelkezik , akkor az értékek ugyanúgy kerülnek átadásra a metódusnak, mint amikor nem referencia változókkal dolgozunk. A paraméterhez egyszerűen hozzárendeljük a másik változó értékét.

Példa:

Kód Leírás
class Solution
{
   public static void fill(String[] array, String value)
   {
      for (int i = 0; i < array.length; i++)
        array[i] = value;
   }

   public static void main(String[] args)
   {
     String[] data = new String[10];
     fill(data, "Hello");
   }
}


A fillkitölti az átadott tömböt ( array) az átadott értékkel ( value).

A fillmetódus meghívásakor a arrayparaméter hivatkozást kap a tömbhöz data. A valueváltozóhoz egy hivatkozás van hozzárendelve a karakterlánc objektumhoz ("Hello").

Így néz ki a memória a metódus meghívása előtt fill :

Hivatkozások átadása a módszerekre

Így néz ki a memória, amikor a fill módszer fut :

Hivatkozások átadása a módszerekre 2

A dataés arrayváltozók ugyanarra a tárolóra vonatkoznak (hivatkozásokat tárolnak) a memóriában.

A valueváltozó a string objektumra ( ) való hivatkozást tárolja "Hello".

A tömb cellái is csak hivatkozásokat tárolnak az objektumra "Hello".

Valójában egyetlen objektum sem duplikálódik – csak a hivatkozások másolódnak.



6. Összehasonlítás a C/C ++ nyelvvel

Az interjúkban néha megkérdezik a Java programozókat, hogyan továbbítják az adatokat a Java metódusaihoz? És néha az a kérdés, hogy az adatokat referencia vagy érték alapján adják át?

Ez a kérdés a C++-ból származik, de Java-ban nem túl értelmes . Java-ban a paraméterekhez mindig egyszerűen az argumentumok értékeit rendeljük hozzá. Tehát a helyes válasz az " érték szerint ".

De készüljön fel arra, hogy elmagyarázza álláspontját , mert azonnal hallhatja a visszavágást: "A primitív típusokat érték, a referenciatípusokat pedig hivatkozás adja át."

Ez a probléma abból a tényből ered, hogy sok Java programozó korábban C++ programozó volt. Ebben a programozási nyelvben nagyon fontos volt a paraméterek metódusoknak való átadásának kérdése.

A Java-ban minden egyértelmű: a primitív típusok értékeket tárolnak, és a referenciatípusok is tárolnak egy értéket – egy hivatkozást. Kérdés, hogy egy változót értéknek tekintünk- e .

A C++ nyelvben egy változó egy objektumra való hivatkozást és magát az objektumot is tárolhatja. Ugyanez igaz a primitív típusokra is: egy primitív változó tárolhat egy értéket, vagy deklarálhatja a változót hivatkozásként egy int. Tehát a félreértések elkerülése érdekében a C++ programozók az objektumot egy hivatkozásra mindig hivatkozásként , magát az objektumot pedig értékként hivatkozzák.

A C++ nyelvben könnyen előfordulhat, hogy az egyik változó tartalmaz egy objektumot, de a másik egy hivatkozást tartalmaz arra az objektumra. Ennek megfelelően nagyon fontos volt a kérdés, hogy egy változó mit tárol – magát az objektumot vagy csak egy hivatkozást rá. Amikor egy objektumot átadtak egy metódusnak, a rendszer átmásolta (ha érték alapján adta át), és nem másolta (ha hivatkozással adta át).

Java-ban ez a kettősség nem létezik, így a helyes válasz: az argumentumok érték alapján kerülnek átadásra a Java metódusoknak . Csak arról van szó, hogy amikor referenciaváltozókról beszélünk, ez az érték referencia.