Archief - [PROG][JAVA] Galgje.java

Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.

forloRn_

Legacy Member
Zever. We hebben het niet over references doorgeven, maar over objecten doorgeven. Een reference is inderdaad passed by value; niemand is echter geïnteresseerd in de reference maar in het object zelf. Vanuit het standpunt van het object bekeken, is het pass by reference.

edit: aan eniac

MilM

Legacy Member
eniac zei:
Mnee. Pass-by-reference bestaat niet in Java, het is strikt pass-by-value.

Vrij verwarrend en wordt op scholen vaak verkeerdelijk aangeleerd als pass-by-reference, maar is het dus niet.

Java op zich is pass by value, maar ik hou niet van die uitdrukking.

Objecten worden simpelweg niet doorgegeven by value, hun referentie wel.
Dus het is te zien hoe je een zin interpreteer.
Ik vind het correct om te zeggen dat parameters by value worden doorgegeven, maar niet om te zeggen dat objecten by value worden doorgegeven (want dat is simpelweg zo niet).

Alhoewel pass by value officieel mss wel juist is, zou er beter een nieuwe term uitgevonden worden. Want 'pass by value' vind ik nog meer verwarrend dan 'pass by reference'. Maar dat laatste kan inderdaad leiden tot misverstanden en fouten (wanneer je verwijzingen met argumenten gaat wijzigen).

[BAT] Hydra

Legacy Member
killgore zei:
ehm, die quote die jij geeft zegt dat de REFERENTIE wordt gekopieerd (net zoals dit in c++ en zo ook gebeurd), niet het object zelf :p. De referentie zelf wordt pass-by-value gedaan (logisch ook), het object wordt niet gekopieerd.

Het is niet omdat java met referenties naar objecten werkt, dat het doorgeven van zulke referenties (pass by) zoiezo by reference gebeurt.

edit: Om vlug te zien of iets pass by value of pass by reference werkt:

Ken aan de doorgegeven parameter een nieuw object toe, als buiten de methode het object dat doorgegeven is veranderd is, ben je met pass by reference bezig, anders niet.

In java geldt dit dus niet:

Code:
Car aCar = new Car("myCar");
changeCar(aCar);
// hier aangekomen tijdens de uitvoering van het programma zal aCar nog steeds de "myCar" car zijn.
...

private static void changeCar(Car car) {
	car = new Car("changedCar");
}

in c++ kan je door gebruik te maken van pointers de car wel laten veranderen.

forloRn_

Legacy Member
Dat is gewoonweg fout. Pass by reference wilt gewoon zeggen dat je een reference naar een object doorgeeft in plaats van het object zelf. De parameter car van changeCar(Car car) is gewoon een lokale variabele van de method, die bij de aanroep van de method een reference naar aCar als waarde krijgt. Verander je de waarde van car, dan gaat aCar daar natuurlijk geen last van hebben; roep je daarentegen methods aan op car, dan wijzigt het object wel, omdat car en aCar naar hetzelfde object wijzen.

Wat je hierboven beschrijft is een reference by reference doorgeven.

[BAT] Hydra

Legacy Member
forloRn_ zei:
Dat is gewoonweg fout. Pass by reference wilt gewoon zeggen dat je een reference naar een object doorgeeft in plaats van het object zelf. De parameter car van changeCar(Car car) is gewoon een lokale variabele van de method, die bij de aanroep van de method een reference naar aCar als waarde krijgt. Verander je de waarde van car, dan gaat aCar daar natuurlijk geen last van hebben; roep je daarentegen methods aan op car, dan wijzigt het object wel, omdat car en aCar naar hetzelfde object wijzen.
Wat je hierboven beschrijft is een reference by reference doorgeven.

Neen.

Pass by reference wilt zeggen dat als je een variable doorgeeft als parameter, er eigenlijk geen verschil is tussen de variabele buiten de methode en de parameter binnen de methode. Als je binnen de methode eender welke operatie dat betrekking heeft op de parameter binnen de methode uitvoert, dan zal diezelfde operatie gebeuren op de variabele buiten de methode.

Mijn voorbeeld toont aan dat niet elke operatie "parallel" wordt uitgevoerd op zowel de parameter binnen de methode als de variabele buiten de methode. Het volledige "parallel" zijn is nochthans noodzakelijk om over "pass by reference" te kunnen spreken.

Mijn tekst geeft een handig truukje om in een OO taal te kunnen zien of een parameter by reference is meegegeven: ken een nieuw object toe aan de parameter en kijk of dit nieuw object ook is toegekend aan de variabele buiten de methode.

forloRn_ zei:
Dat is gewoonweg fout. Pass by reference wilt gewoon zeggen dat je een reference naar een object doorgeeft in plaats van het object zelf.

Je begrijpt het verkeerd...

In compiler terms, "pass by reference" means if you pass a variable into a method, its value can be modified. This is possible in many languages, like Pascal, Ada, and C++, but not in many other languages like C and Java. (Pascal had "var", Ada had "out", C++ had "&")

Note very clearly that a lot of people confuse the "reference" terminology with respect to Java's references to objects and pass by reference calling semantics. The fact is, in dealing with Java's references to objects, a copy of the reference's value is what is passed to the method -- it's passed by value. This is, for example, why you cannot mutate the (original, caller's) reference to the object from inside the called method.

In het vetgedrukt staat wat mijn voorbeeld aangeeft.

killgore

Legacy Member
[BAT] Hydra;9404803 zei:
Het is niet omdat java met referenties naar objecten werkt, dat het doorgeven van zulke referenties (pass by) zoiezo by reference gebeurt.

edit: Om vlug te zien of iets pass by value of pass by reference werkt:

Ken aan de doorgegeven parameter een nieuw object toe, als buiten de methode het object dat doorgegeven is veranderd is, ben je met pass by reference bezig, anders niet.

In java geldt dit dus niet:

Code:
Car aCar = new Car("myCar");
changeCar(aCar);
// hier aangekomen tijdens de uitvoering van het programma zal aCar nog steeds de "myCar" car zijn.
...

private static void changeCar(Car car) {
	car = new Car("changedCar");
}

in c++ kan je door gebruik te maken van pointers de car wel laten veranderen.

Hiermee bewijs je niets hoor :x. Enkel dat de referentie zelf pass-by-value is, zoals ik al eerder zei. Het object zelf wordt niet gekopiëerd. Doe dit in C++ met pointers en je komt volledig het zelfde resultaat (want de pointer ZELF wordt gekopiëerd, het object waarnaar hij wijst niet).

Probeer deze code eens en je zal zien dat ik gelijk heb:

Code:
import java.io.*;

class Test {
	private int var = 0;
	public static void main(String[] args){
		Test t = new Test();
		t.print();
		testje(t);
		t.print();
	}
	
	public void setVar(int a)
	{
		var= a;
	}

	public void print() {
		System.out.println(""+var);
	}
	
	public static void testje(Test ref)
	{
		ref.setVar(-1);
	}
}
Dat is nu wat pass-by-reference wilt zeggen. Je kopieert enkel de referentie, niet het object, als je dus een wijziging op het object doet zal het object "globaal" wijzigen. Jouw code deed een bewerking op de referentievariabele, nl een nieuw adres toekennen, dit heeft niets met het object zelf te maken ;).

[BAT] Hydra

Legacy Member
killgore zei:
Hiermee bewijs je niets hoor :x. Enkel dat de referentie zelf pass-by-value is, zoals ik al eerder zei. Het object zelf wordt niet gekopiëerd. Doe dit in C++ met pointers en je komt volledig het zelfde resultaat (want de pointer ZELF wordt gekopiëerd, het object waarnaar hij wijst niet).

Probeer deze code eens en je zal zien dat ik gelijk heb:

Code:
import java.io.*;

class Test {
	private int var = 0;
	public static void main(String[] args){
		Test t = new Test();
		t.print();
		testje(t);
		t.print();
	}
	
	public void setVar(int a)
	{
		var= a;
	}

	public void print() {
		System.out.println(""+var);
	}
	
	public static void testje(Test ref)
	{
		ref.setVar(-1);
	}
}
Dat is nu wat pass-by-reference wilt zeggen. Je kopieert enkel de referentie, niet het object, als je dus een wijziging op het object doet zal het object "globaal" wijzigen. Jouw code deed een bewerking op de referentievariabele, nl een nieuw adres toekennen, dit heeft niets met het object zelf te maken ;).

In c++ kan je kiezen of je aan pass-by-value of pass-by-reference doet, in java niet, in java kan je enkel aan pass-by-value doen. Wat jij toont is hoe je pass-by-value in c++ doet.

Als je wil weten wat het verschil is tussen "pass-by-value" en "pass-by-reference" in c++ kan je hier eens naar kijken: http://www.tech-recipes.com/c_programming_tips1232.html

Met mijn voorbeeld toon ik trouwens wel iets aan. Op deze pagina staat het ook uitgelegd: http://www.jguru.com/faq/view.jsp?EID=430996

killgore

Legacy Member
[BAT] Hydra;9405345 zei:
In c++ kan je kiezen of je aan pass-by-value of pass-by-reference doet, in java niet, in java kan je enkel aan pass-by-value doen.

Met mijn voorbeeld toon ik wel iets aan. Op deze pagina staat ook uitgelegd: http://www.jguru.com/faq/view.jsp?EID=430996

n/o, maar die mannen interpreteren pass-by-value en pass-by-reference toch zwaar buiten bekende normen hoor :x.
Zo kan je ALLES pass-by-value noemen. Want inderdaad, de argument-variabelen zelf worden pass-by-value gekopiëerd, maar het gaat hem niet daarom :x.

[BAT] Hydra

Legacy Member
Neen. Dat is gewoon wat "pass-by-value" en "pass-by-reference" betekenen hoor...

De meeste mensen denken gewoon omdat er referenties (pointers) meegegeven worden er zoiezo aan "pass-by-reference" wordt gedaan. Terwijl er in Java gewoon een kopie van een meegegeven referentie wordt gemaakt. (dus by value)

edit: Als je de literatuur erop nagaat zal je zien dat overal deze betekenissen "pass-by-value" en "pass-by-reference" gehanteerd worden hoor :).

edit2: hier staat alles nog eens mooi uitgelegd: http://javadude.com/articles/passbyvalue.htm

In de voorgaande artikels wordt eigenlijk hetzelfde uitgelegd als in mijn posts, enkel veel uitgebreider.

MilM

Legacy Member
Het probleem van miscommunicatie zit hem in het feit dat objecten by reference worden doorgegeven en de argumenten zelf by value.

Aangezien de argumenten by value doorgegeven worden, is java strikt gezien inderdaad by value.
Maar het is meer dna normaal dat men in een objecttaal vanuit het standpunt van een object gaat gaan kijken.

Pass by value is instinctief volgens mij een slechte benaming voor talen als java.

Er zijn 4 mogelijke combinaties (argumenten by reference/value; objecten by reference/value) en het zou dan ook veel beter zijn om beiden in de benaming te betrekken dan enkel hoe de argumenten doorgegeven worden.

Bijvoorbeeld in het geval van java 'by referencevalue' (referentiewaarde) of 'by value - reference' (waarde van de referentie).

Want voor veel meer situaties, zeker voor beginnelingen, is het van belang hoe het object wordt doorgegeven (by reference) en niet het argument zelf (by value).

[BAT] Hydra

Legacy Member
MilM zei:
Het probleem van miscommunicatie zit hem in het feit dat objecten by reference worden doorgegeven en de argumenten zelf by value.

Aangezien de argumenten by value doorgegeven worden, is java strikt gezien inderdaad by value.
Maar het is meer dna normaal dat men in een objecttaal vanuit het standpunt van een object gaat gaan kijken.

Pass by value is instinctief volgens mij een slechte benaming voor talen als java.

Er zijn 4 mogelijke combinaties (argumenten by reference/value; objecten by reference/value) en het zou dan ook veel beter zijn om beiden in de benaming te betrekken dan enkel hoe de argumenten doorgegeven worden.

--> het lijkt me toch duidelijk dat met pass-by-* enkel het doorgeven (pass) van een variable als argument in een methode wordt bedoeld?

Bijvoorbeeld in het geval van java 'by referencevalue' (referentiewaarde) of 'by value - reference' (waarde van de referentie).

Want voor veel meer situaties, zeker voor beginnelingen, is het van belang hoe het object wordt doorgegeven (by reference) en niet het argument zelf (by value).

In je uitleg zet je meermaals dat een object doorgegeven wordt. Dit is onmogelijk in java, en mag je als dusdanig ook nooit schrijven. Het verwart lezers (zoals ik) die proberen te begrijpen wat je bedoelt.

Er is in de academische wereld (en daarbuiten ook) een conventie die bepaalt wat "pass-by-reference" en "pass-by-value" precies inhouden. Als je je gewoon aan die conventie houdt kan er onmogelijk verwarring zijn. Het probleem zit em in het feit dat mensen vlug hun eigen definitie van pass-by-reference verzinnen, die niet gelijkloopt met de academische definitie.

MilM

Legacy Member
Ik zeg nergens dat een object wordt doorgegeven.
Ik zeg dat een referentie wordt doorgegeven.

De manier waarop dat wordt doorgegeven kan verschillend zijn (door een kopie of niet)

'pass by value' verwart ook veel lezers.
De waarde van wat ? Het object of van de referentie ?

Daarom dat ik een dubbele benaming ook beter vind.

"Een object wordt doorgegeven door een kopie (waarde) van de referentie van het object".
Er is niets mis met deze zin imo

forloRn_

Legacy Member
'k Zie [BAT]Hydra zijn of haar punt wel ondertussen. 't Is nu eenmaal zo dat een reference in Java iets anders is dan een reference in C++. Dereferencing (expliciet met * op een pointer of impliciet met een reference) kan nu eenmaal niet in Java.

'k Vind dat het de discussie hier niet waard is. In elk boek over Java leer je dat primitives doorgegeven worden by value, en objecten by reference, en ik denk dat de meesten onder ons wel weten wat daar precies mee bedoeld wordt.

[BAT] Hydra

Legacy Member
MilM zei:
"Een object wordt doorgegeven door een kopie (waarde) van de referentie van het object".
Er is niets mis met deze zin imo

Objecten worden niet doorgegeven in java, hier is een verbeterde versie van je zin:

"Een referentie naar een object wordt doorgegeven door een kopie (waarde) van de referentie van het object".

[BAT] Hydra

Legacy Member
forloRn_ zei:
'k Zie [BAT]Hydra zijn of haar punt wel ondertussen. 't Is nu eenmaal zo dat een reference in Java iets anders is dan een reference in C++. Dereferencing (expliciet met * op een pointer of impliciet met een reference) kan nu eenmaal niet in Java.

'k Vind dat het de discussie hier niet waard is. In elk boek over Java leer je dat primitives doorgegeven worden by value, en objecten by reference, en ik denk dat de meesten onder ons wel weten wat daar precies mee bedoeld wordt.

Het is niet enkel mijn punt, het is het punt van iedereen die er wat meer over weet! Iemand die schrijft in zijn boek dat in java objecten by reference worden doorgegeven zal er zelf niet veel van weten...
Iemand die schrijft in zijn boek dat in java enkel objecten gemanipuleerd kunnen worden door referenties naar deze objecten te gebruiken, zal er al veel meer van af weten...

MilM

Legacy Member
Ik geef toe dat mijn zin een slecht voorbeeld was om mijn punt duidelijk te maken.
Maar ik blijf bij mijn punt.

Er zijn ruim gezien 4 situaties en 'by value' is geen ideale benaming voor java.
Aangezien niet de waarde zelf, maar de waarde van een referentie naar een object wordt doorgegeven.

Ik heb trouwens nergens gezegd dat u of eniac niet correct waren (integendeel zelfs).

[BAT] Hydra

Legacy Member
De benamingen scheppen inderdaad verwarring.

Maar als iedereen eerst de moeite zou doen om wat te lezen ivm "pass-by-reference" en "pass-by-value" alvorens er beweringen over te doen, zou er heel wat minder verwarring bestaan :).

MilM

Legacy Member
Die verwarring zal moeilijk weg te krijgen zijn.
De reden ligt in het taalgebruik.

Een voorbeeld:
Je kunt een steamaccount doorgeven door enkel het passwoord en het emailadres door te geven.
Dan zeg je ook in de gewone taal "ik heb mijn steamaccount doorgegeven", terwijl je in het echt een emailadres en passwoord hebt doorgegeven (waarmee iemand toegang krijgt tot een steamaccount).

Ik geef dat voorbeeld aan omdat je daarstraks zei dat er geen object wordt doorgegeven, maar een referentie.
Dat klopt ook, maar met de bedoeling natuurlijk om in die andere methode aan het object te kunnen.
Het is dus maar te zien wat je verstaat onder 'doorgeven'.

Ik heb een steamaccount doorgegeven door het passwoord en email door te sturen. (die zin van mij)
Ik heb een passwoord en email doorgegeven door een kopie te versturen. (uw verbeterde versie)

Beiden zijn volgens de gewone taal niet fout.
In Java geldt er 'by value', maar wil dat zeggen dat het volgens ons taalgebruik fout is om te zeggen dat objecten doorgegeven worden door een referentie ?
Het is maar te zien vanuit welk standpunt.

Die conventie is er inderdaad en java zelf is dus 'by value'. Het is ook mijn bedoeling niet om daarover te discussieren.

Ik ga nu wel ver met deze post :p. Maar ik weet niet of je weet waar ik naartoe wil ?
Ik heb het over ons taalgebruik en niet over de conventie voor alle duidelijkheid.
Zie dit dus als een nieuwe discussie over de natuurlijke reden achter die verwarring (en zeker niet als een post om het 'by value' te ontkrachten).

EDIT: ik bedoel dus maar of je kunt stellen dat het fout is om te zeggen dat 'objecten worden doorgegeven door een referentie (by reference)' in onze gewone taal ?

killgore

Legacy Member
MilM zei:
Het probleem van miscommunicatie zit hem in het feit dat objecten by reference worden doorgegeven en de argumenten zelf by value.

Aangezien de argumenten by value doorgegeven worden, is java strikt gezien inderdaad by value.
Maar het is meer dna normaal dat men in een objecttaal vanuit het standpunt van een object gaat gaan kijken

Ik ken niet veel talen (asm is eignelijk enige) waar bij het argument zelf by-reference wordt meegegeven. In C, C++, C# wordt het argument ook by value meegegeven ;).

Toch spreekt men daar altijd over pass-by-reference, tenzij men het echt over de pointer-variabele (of reference-variabele) zelf heeft en men zelfs niet kijkt naar wat het juist wijst (dan gaat men in C/C++ zelfs vaak gewoon met void* werken), wat een zware minderheid van de gevallen is.

Ik gaf hydra dan ook geen ongelijk, ik vind gewoon dat java-mensen in dit geval echt zeer tegendraads doen tegen de standaard gebruikte termen. Als men over de objecten spreekt (en dat is praktisch altijd zo) is java pass-by-reference.

[BAT] Hydra

Legacy Member
killgore zei:
Als men over de objecten spreekt (en dat is praktisch altijd zo) is java pass-by-reference.

Het is helemaal niet zo dat de java mensen tegendraads zijn. De mensen die jouw definitie gebruiken weten er niets van maar denken dat ze er iets over weten. Je gaat nergens in een hoog aangeschreven boek jouw definitie van "call-by-reference" terugvinden. Er is maar 1 juiste definitie, en iedereen die erover wenst te praten zou deze moeten gebruiken...

Hier is een voorbeeld in c# waar er opnieuw de juiste definitie van call-by-value en call-by-reference worden gebruikt

by value:

Code:
private void CallMe(int i)
{
    i = 100;  //i is assigned a value of 100
}

public void TestCall()
{
   int i = 10;
   CallMe(i);
   MessageBox.Show(i.ToString());  // The changed value is not reflected and the
                            //MessageBox shows 10 and not 100.
}

by reference:

Code:
private void CallMe(ref int i)
{
    i = 100;  //i is assigned a value of 100
}

public void TestCall()
{
   int i = 10;
   CallMe(ref i);
   MessageBox.Show(i.ToString());  // The changed value is reflected and the
                            //MessageBox now shows 100.
}

bron: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2340086&SiteID=1

In dit voorbeeld wordt een int by value en by reference doorgegeven. Zoals je kan zien voorziet c# expliciet een manier om variabelen by reference door te geven. Hiervoor maak je gebruik van het ref keyword. Op dezelfde manier zou je een referentie ook by value en by reference kunnen doorgeven. (C# werkt ook met referenties naar objecten)

Het ref keyword illustreert mooi het verschil tussen pass-by-reference (gebruik maken van ref keyword, de parameter binnen de methode is een alias voor de parameter buiten de methode) en geen pass by-reference (referenties doorgeven zoals dit in java gedaan wordt)

Je moet het uit je hoofd zetten dat het volgende juist is: Als men over de objecten spreekt (en dat is praktisch altijd zo) is java pass-by-reference.

Het is VOLLEDIG fout! Je gaat niemand met wat meer kennis van zaken vinden die zoiets gaat bevestigen...
Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.
Terug
Bovenaan