1. Referentievariabelen

In de Java-taal zijn er twee soorten variabelen: primitieve variabelen en al het andere. Toevallig gaan we het nu hebben over "al het andere".

In feite zou het juister zijn om te zeggen dat er primitieve variabelen en referentievariabelen zijn . Dus wat zijn deze referentievariabelen?

In tegenstelling tot primitieve typen, waarvan de variabelen waarden rechtstreeks opslaan, slaan verwijzingsvariabelen verwijzingen naar objecten op. Dat wil zeggen, er is ergens in het geheugen een object en de referentievariabele slaat eenvoudigweg het adres van dit object op in het geheugen (een verwijzing naar het object).

Alleen primitieve typen slaan waarden direct op in variabelen. Alle andere typen slaan alleen een objectreferentie op . Trouwens, u bent al twee van dergelijke soorten variabelen tegengekomen: Stringvariabelen en arrayvariabelen .

Zowel een array als een string zijn objecten die ergens in het geheugen zijn opgeslagen. Stringvariabelen en matrixvariabelen slaan alleen verwijzingen naar objecten op.

Referentievariabelen in Java

int a, int b and double dzijn primitieve variabelen die hun waarden in zichzelf opslaan.

Een String strvariabele is een referentie en slaat het adres (referentie) naar een Stringobject op in het geheugen.

Bij het toekennen van een primitieve waarde aan een variabele van een primitief type, wordt de waarde ervan gekopieerd (gedupliceerd). Bij het toewijzen van een referentievariabele wordt alleen het adres van het object gekopieerd - het object zelf wordt niet gekopieerd .


2. Waar gaan referenties over?

Wat is het fundamentele verschil tussen referentievariabelen en primitieve variabelen?

Een primitieve variabele is als een doos: je kunt er een bepaalde waarde in opslaan. Een referentievariabele lijkt meer op een stuk papier met een telefoonnummer erop.

Een auto versus sleutels van de auto

Stel je voor dat je besluit om je vriend een auto te geven voor zijn verjaardag. Je gaat hem niet in een doos wikkelen en meenemen: daar is de auto te groot voor.

Het is veel handiger om alleen de autosleutels in een doos te presenteren die groot genoeg is om ze te bevatten. Je vriend zal alles begrijpen als hij de sleutels uit de doos haalt. U hoeft niet de hele auto mee te sjouwen, u kunt gewoon de sleutels overhandigen.

Een persoon versus haar telefoonnummer

Of hier is een andere vergelijking: een persoon en haar telefoonnummer. Een telefoonnummer is niet de persoon, maar een telefoonnummer kan worden gebruikt om haar te bellen, haar om informatie te vragen of instructies te geven.

Evenzo wordt een referentie gebruikt om met een object te communiceren. Alle objecten interageren met elkaar door middel van referenties. In plaats van "mensen uit te wisselen", wisselen we gewoon telefoonnummers uit.

Bij het toewijzen van een waarde aan een primitieve variabele, wordt de waarde ervan gekopieerd (gedupliceerd). Bij het toekennen van een waarde aan een referentievariabele wordt alleen het adres (telefoonnummer) van het object gekopieerd — het object zelf wordt niet gekopieerd.

Een referentie biedt nog een voordeel: u kunt een objectreferentie doorgeven aan een methode, en de methode zal het object kunnen wijzigen (veranderen) door de verwijzing ernaar te gebruiken, zijn methoden aan te roepen en toegang te krijgen tot gegevens binnen het object.


3. Referenties toekennen

Bij het toewijzen van referentievariabelen wordt alleen het objectadres in het geheugen toegewezen. Objecten zelf verschijnen of verdwijnen niet.

Deze benadering vermijdt het kopiëren van grote hoeveelheden geheugen. Als u een heel groot object aan een methode moet doorgeven, geven we alleen de objectreferentie door en dat is alles. De referentie neemt veel minder ruimte in beslag.

Referenties toekennen

De grootte van alle referentievariabelen (ongeacht hun type) is hetzelfde - 4 bytes (zoals een int). Maar! Als uw toepassing op een 64-bits Java-machine draait, zijn alle verwijzingen 8 bytes (64 bits) groot.

Bovendien kunnen referenties alleen aan elkaar worden toegewezen. U kunt referenties niet wijzigen of willekeurige waarden toewijzen aan referentievariabelen:

Code Beschrijving
String hello = "Hello";
String s = hello;
Dit is toegestaan
String hello = "Hello";
hello++;
Maar dit is niet toegestaan
String hello = 0x1234;
En dit is niet toegestaan

4. Een nullreferentie

En wat slaat een referentievariabele op als er nog niets aan is toegewezen?

Het slaat een null- referentie op. nullis een speciaal Java-sleutelwoord dat de afwezigheid van een referentie betekent (een lege referentie). De nullwaarde kan aan elke referentievariabele worden toegewezen.

Alle referentievariabelen zijn nulltenzij er een soort referentie aan hen is toegewezen.

Voorbeelden:

Code Beschrijving
class Person
{
   public static String name;
   public static int age;
}


De String namevariabele heeft een standaardwaarde: null.
De int agevariabele heeft een standaardwaarde: 0.

Lokale variabelen waaraan geen waarde is toegewezen, worden beschouwd als niet-geïnitialiseerd voor zowel primitieve als referentietypen.

Als een variabele een verwijzing naar een object opslaat, en u wilt de waarde van de variabele wissen, wijs er dan gewoon een null-referentie aan toe.

Code Beschrijving
String s = null;
s = "Hello";
s = null;
swinkels null.
sslaat een verwijzing op naar een string object
sstores null.

5. Verwijzingen naar methoden doorgeven

Als een methode parameters heeft die van het referentietype zijn , worden waarden op dezelfde manier aan de methode doorgegeven als bij het werken met niet-referentievariabelen. De parameter krijgt eenvoudigweg de waarde van de andere variabele toegewezen.

Voorbeeld:

Code Beschrijving
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");
   }
}


Het fillvult de doorgegeven array ( array) met de doorgegeven waarde ( value).

Wanneer de fillmethode wordt aangeroepen, arraykrijgt de parameter een verwijzing naar de dataarray toegewezen. De valuevariabele krijgt een verwijzing toegewezen naar het tekenreeksobject ("Hallo").

Zo ziet het geheugen eruit voordat de fill methode wordt aangeroepen:

Verwijzingen naar methoden doorgeven

Zo ziet het geheugen eruit als de fill methode wordt uitgevoerd :

Verwijzingen naar methoden doorgeven 2

De variabelen dataen arrayverwijzen naar (referenties opslaan naar) dezelfde container in het geheugen.

De valuevariabele slaat een verwijzing op naar het tekenreeksobject ( "Hello").

De cellen van de array slaan ook alleen verwijzingen naar het "Hello"object op.

In feite worden er geen objecten gedupliceerd - alleen referenties worden gekopieerd.



6. Vergelijking met de C/C++ taal

In interviews wordt Java-programmeurs soms gevraagd hoe gegevens worden doorgegeven aan methoden in Java? En soms is de vraag of gegevens worden doorgegeven op basis van referentie of op basis van waarde?

Deze vraag komt uit C++, maar is niet erg zinvol in Java . In Java krijgen parameters altijd eenvoudigweg de waarden van de argumenten toegewezen. Het juiste antwoord zou dus " op waarde " zijn.

Maar wees voorbereid om uw standpunt uit te leggen , aangezien u mogelijk onmiddellijk het antwoord hoort: "primitieve typen worden doorgegeven door waarde, en referentietypen worden doorgegeven door referentie."

De oorzaak van dit probleem komt voort uit het feit dat veel Java-programmeurs in het verleden C++-programmeurs waren. In die programmeertaal was de vraag hoe parameters worden doorgegeven aan methoden erg belangrijk.

In Java is alles ondubbelzinnig: primitieve typen slaan waarden op en referentietypen slaan ook een waarde op - een referentie. Het gaat erom of een variabele als een waarde wordt beschouwd .

In C++ kan een variabele zowel een verwijzing naar een object als het object zelf opslaan. Hetzelfde gold voor primitieve typen: een primitieve variabele kon een waarde opslaan of de variabele declareren als een verwijzing naar een int. Dus, om verwarring te voorkomen, verwijzen C++-programmeurs altijd naar het object naar een referentie als een referentie en het object zelf als een waarde.

In C++ zou je gemakkelijk de situatie kunnen hebben waarin de ene variabele een object bevat, maar de andere een verwijzing naar dat object bevat. Dienovereenkomstig was de vraag wat een variabele opslaat - het object zelf of alleen een verwijzing ernaar - erg belangrijk. Wanneer een object aan een methode werd doorgegeven, werd het gekopieerd (indien doorgegeven door waarde) en niet gekopieerd (indien doorgegeven door verwijzing).

In Java bestaat deze dualiteit niet, dus het juiste antwoord is: argumenten worden doorgegeven aan Java-methoden door value . Alleen als we het hebben over referentievariabelen, is deze waarde een referentie.