Java wordt doorgegeven per waarde, niet per referentie

Inleiding

Veel Java-programmeurs vragen zich af of Java doorgegeven wordt per waarde of per referentie. Dit artikel vat samen waarom Java altijd doorgegeven wordt per waarde.

Ten eerste, wat betekenen doorgeven per waarde en doorgeven per referentie?

  • Doorgeven per waarde: De waarden van de methodeparameters worden gekopieerd naar een andere variabele en vervolgens wordt het gekopieerde object doorgegeven aan de methode. De methode gebruikt de kopie.
  • Doorgeven per referentie: Een alias of referentie naar de werkelijke parameter wordt doorgegeven aan de methode. De methode heeft toegang tot de werkelijke parameter.

Vaak ontstaat verwarring rond deze termen als gevolg van het concept van de objectreferentie in Java. Technisch gezien wordt in Java altijd doorgegeven per waarde, want zelfs als een variabele een referentie naar een object bevat, is die objectreferentie een waarde die de locatie van het object in het geheugen vertegenwoordigt. Objectreferenties worden dus doorgegeven per waarde.

Zowel referentietypen als primitieve datatypen worden doorgegeven per waarde. Lees meer over datatypen in Java.

Naast het begrijpen van datatypen is het ook belangrijk om geheugenallocatie in Java te begrijpen, omdat referentietypen en primitieve datatypen op verschillende manieren worden opgeslagen.

Demonstratie van passeren per waarde

Het volgende voorbeeld demonstreert hoe waarden worden doorgegeven in Java.

Het voorbeeldprogramma maakt gebruik van de volgende klasse:

public class Balloon {

	private String color;

	public Balloon() {}
	
	public Balloon(String c) {
		this.color = c;
	}
	
	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}
}

Het volgende voorbeeldprogramma gebruikt een generieke methode, swap(), die twee variabelen verwisselt. Een andere methode, changeValue(), probeert de variabelewaarden te wijzigen.

public class Test {

	public static void main(String[] args) {

		Balloon red = new Balloon("Red"); // geheugenreferentie = 50
		Balloon blue = new Balloon("Blue"); // geheugenreferentie = 100
		
		swap(red, blue);
		System.out.println("After the swap method executes:");
		System.out.println("`red` color value = " + red.getColor());
		System.out.println("`blue` color value = " + blue.getColor());
		
		changeValue(blue);
		System.out.println("After the changeValue method executes:");
		System.out.println("`blue` color value = " + blue.getColor());
		
	}

	// Generieke verwisselmethode
	public static void swap(Object o1, Object o2){
		Object temp = o1;
		o1 = o2;
		o2 = temp;
	}

	private static void changeValue(Balloon balloon) { // ballon = 100
		balloon.setColor("Red"); // ballon = 100
		balloon = new Balloon("Green"); // ballon = 200
		balloon.setColor("Blue"); // ballon = 200
	}

}

Wanneer u het voorbeeldprogramma uitvoert, krijgt u de volgende uitvoer:

Output
After the swap method executes: 'red' color value = Red 'blue' color value = Blue After the changeValue method executes: 'blue' color value = Red

De uitvoer toont aan dat de methode swap() de kleurwaarden van de originele objecten niet heeft verwisseld. Dit helpt te laten zien dat Java passeren per waarde is, aangezien de methode swap() alleen werkt met kopieën van de oorspronkelijke objectreferentiewaarden.

Deze test van de swap()-methode kan worden gebruikt met elke programmeertaal om te controleren of het passeren per waarde of per referentie is.

Het Voorbeeld van de swap()-Methode Uitgelegd

Wanneer je de new-operator gebruikt om een instantie van een klasse te maken, wordt het object aangemaakt en bevat de variabele de locatie in het geheugen waar het object is opgeslagen.

Balloon red = new Balloon("Red");
Balloon blue = new Balloon("Blue");

Hier volgt een stapsgewijze uitleg van wat er gebeurt wanneer de swap()-methode wordt uitgevoerd:

  • Stel dat red wijst naar geheugenlocatie 50 en blue wijst naar geheugenlocatie 100, en dat dit de geheugenlocaties zijn van beide Balloon-objecten.

  • Wanneer de klasse de swap()-methode aanroept met de variabelen red en blue als argumenten, worden twee nieuwe objectvariabelen, o1 en o2, gecreëerd. o1 en o2 wijzen ook naar geheugenlocaties 50 en 100 respectievelijk.

  • De volgende codefragment legt uit wat er gebeurt binnen de swap() methode:

    public static void swap(Object o1, Object o2) { // o1 = 50, o2 = 100
    	Object temp = o1; // wijs de objectreferentiewaarde van o1 toe aan temp: temp = 50, o1 = 50, o2 = 100
    	o1 = o2; // wijs de objectreferentiewaarde van o2 toe aan o1: temp = 50, o1 = 100, o2 = 100
    	o2 = temp; // wijs de objectreferentiewaarde van temp toe aan o2: temp = 50, o1 = 100, o2 = 50
    } // methode beëindigd
    
  • De waarden van o1 en o2 worden omgewisseld, maar omdat de waarden kopieën zijn van de geheugenlocaties van red en blue, verandert er niets aan de waarden van de red en blue kleurwaarden.

Aangezien de variabelen de verwijzing naar de objecten bevatten, is het een veelvoorkomende fout om aan te nemen dat je de referentie doorgeeft en dat Java pass by reference is. Echter, je geeft een waarde door, namelijk een kopie van de referentie, en daarom is het pass by value.

De voorbeeldmethode changeValue() uitgelegd

De volgende methode in het voorbeeldprogramma verandert de kleurwaarde van het object waarnaar de variabele blue verwijst:

private static void changeValue(Balloon balloon) { // balloon = 100
	balloon.setColor("Red"); // balloon = 100
	balloon = new Balloon("Green"); // balloon = 200
	balloon.setColor("Blue"); // balloon = 200
}

Hier is een stapsgewijze uitleg van wat er gebeurt binnen de changeValue()-methode:

  • De klasse roept de changeValue()-methode aan op de variabele blue die verwijst naar geheugenlocatie 100. De eerste regel creëert een referentie die ook wijst naar geheugenlocatie 100. De kleurwaarde van het object op geheugenlocatie 100 wordt veranderd in "Red".

  • De tweede regel creëert een nieuw object (met kleurwaarde "Green"). Het nieuwe object bevindt zich op geheugenlocatie 200. Eventuele verdere methoden die worden uitgevoerd op de variabele balloon hebben betrekking op het object op geheugenlocatie 200 en hebben geen invloed op het object op geheugenlocatie 100. De nieuwe variabele balloon overschrijft de referentie die is gemaakt in regel 1 en de referentie van balloon uit regel 1 is niet langer toegankelijk binnen deze methode.

  • De derde regel verandert de kleurwaarde van het nieuwe Balloon-object op geheugenlocatie 200 naar "Blauw", maar heeft geen invloed op het oorspronkelijke object waarnaar wordt verwezen door blauw op geheugenlocatie 100. Dit verklaart waarom de laatste regel van de uitvoer van het voorbeeldprogramma blauwe kleurwaarde = Rood afdrukt, wat de verandering vanaf regel 1 weerspiegelt.

Conclusie

In dit artikel heb je geleerd waarom Java pass-by-value is. Ga verder met je leerproces met meer Java tutorials.

Source:
https://www.digitalocean.com/community/tutorials/java-is-pass-by-value-and-not-pass-by-reference