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: String
variabelen en arrayvariabelen .
Zowel een array als een string zijn objecten die ergens in het geheugen zijn opgeslagen. String
variabelen en matrixvariabelen slaan alleen verwijzingen naar objecten op.
int a, int b and double d
zijn primitieve variabelen die hun waarden in zichzelf opslaan.
Een String str
variabele is een referentie en slaat het adres (referentie) naar een String
object 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.
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 |
---|---|
|
Dit is toegestaan |
|
Maar dit is niet toegestaan |
|
En dit is niet toegestaan |
4. Een null
referentie
En wat slaat een referentievariabele op als er nog niets aan is toegewezen?
Het slaat een null- referentie op. null
is een speciaal Java-sleutelwoord dat de afwezigheid van een referentie betekent (een lege referentie). De null
waarde kan aan elke referentievariabele worden toegewezen.
Alle referentievariabelen zijn null
tenzij er een soort referentie aan hen is toegewezen.
Voorbeelden:
Code | Beschrijving |
---|---|
|
De String name variabele heeft een standaardwaarde: null . De int age variabele 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 |
---|---|
|
s winkels null . s slaat een verwijzing op naar een string object s stores 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 |
---|---|
|
Het fill vult de doorgegeven array ( array ) met de doorgegeven waarde ( value ). |
Wanneer de fill
methode wordt aangeroepen, array
krijgt de parameter een verwijzing naar de data
array toegewezen. De value
variabele krijgt een verwijzing toegewezen naar het tekenreeksobject ("Hallo").
Zo ziet het geheugen eruit voordat de fill
methode wordt aangeroepen:
Zo ziet het geheugen eruit als de fill
methode wordt uitgevoerd :
De variabelen data
en array
verwijzen naar (referenties opslaan naar) dezelfde container in het geheugen.
De value
variabele 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.
GO TO FULL VERSION