1. #1
    Tw33tst3r's Avatar
    Registered
    08/06/03
    Location
    Opglabbeek
    Posts
    1,400
    iTrader
    0
    Mentioned
    0 Post(s)
    Reputation
    0/2

    Java, wanneer passed by reference of passed by value?

    ik volg atm een opleiding java-ontwikkelaar bij de vdab en aangezien de docent mij tot nu toe op zo goed als geen enkele vraag antwoord heeft kunnen geven dacht ik hier es een poging te wagen (andere vragen heeft google mij gelukkig wel al beantwoord)

    als je een String doorgeeft stond in mijn cursus dan gebeurt dit door passing by reference en niet by value
    vb.
    String a = "Test";
    String b = a;
    b = "niet test";

    dan krijgt a ook de waarde "niet test" omdat b simpelweg naar dezelfde plaats in het geheugen verwijst, hence passing by reference

    mijn vraag is nu:
    wat gebeurt er juist als ik bvb een object aanmaak via een constructor of een method aanroep van een object waarbij ik een variabele gebruik als String parameter?
    bvb.
    String type = "mountainbike";

    Fiets.setType(type);

    method heeft dan volgende body:
    Public void setType(String type){
    this.type = type;
    }

    als ik dan nadien in main de waarde van type verander dan verandert uiteraard de property van mijn object Fiets niet, dat is logisch qua gebruik maar op dat moment pass ik eigenlijk toch een reference variabele en niet de waarde van die String?

    nu ik had al het idee dat dit kwam omdat de property type enkel binnen de class block bestaat en dat deze daarom niet verandert maar waarom dan ook niet als deze public is en bijgevolg buiten de scope van het block valt?

    andere optie dak kon bedenken was dat op het moment dat de method gecalled wordt deze de waarde van de string doorgeeft maar dat spreekt dan weer mijn cursus tegen

    is mss een stomme vraag en ik ben ondertussen ook al veel verder in mijn cursus mr ik vroeg mij dat ineens af toen ik vr de zoveelste keer een reference variabele als parameter gebruikte
    no votes  

  2. #2
    Jack's Avatar
    Registered
    09/11/02
    Location
    B
    Posts
    886
    iTrader
    1 (100%)
    Mentioned
    2 Post(s)
    Reputation
    0/8
    dit probleem komt eigenlijk alleen bij Strings voor. In Java is het simpel: primitives worden altijd by value doorgegeven, objecten altijd by reference.

    Echter is een String beide... technisch gezien is een String een object, maar het is eigenlijk ook een primitive, of laat zich toch althans zo gebruiken. Ik denk dat in method calls (wat constructors in essentie ook zijn) Strings by value gepasst worden.
    no votes  

  3. #3
    Cycloon's Avatar
    Registered
    18/01/04
    Location
    Melle
    Posts
    10,535
    iTrader
    56 (100%)
    Mentioned
    0 Post(s)
    Reputation
    27/102
    Ook opletten met Integer, Double, Float, ... Bij een methode worden die ook doorgeven by value en niet by reference. Nogal vreemd natuurlijk omdat het net wrapperklassen zijn met de bedoeling om van een primitief ding een object te maken.
    “In terms of how we evaluate schooling, everything is about working by yourself. If you work with someone else, it’s called cheating. Once you get out in the real world, everything you do involves working with other people.”
    PSN: Cycloon - Final Fantasy XIV: A realm reborn character
    no votes  

  4. #4
    forloRn_'s Avatar
    Registered
    23/11/03
    Location
    Landeurp
    Posts
    1,791
    iTrader
    0
    Mentioned
    0 Post(s)
    Reputation
    10/17
    Quote Originally Posted by Tw33tst3r View Post
    This quote is hidden because you are ignoring this member. Show
    vb.
    String a = "Test";
    String b = a;
    b = "niet test";

    dan krijgt a ook de waarde "niet test" omdat b simpelweg naar dezelfde plaats in het geheugen verwijst, hence passing by reference
    Blijkbaar niet zo simpelweg, want dit is verkeerd. b wijst naar "niet test", terwijl a nog altijd naar "Test" wijst.

    De referentie a heb je op geen enkel punt veranderd, die wijst dus nog altijd naar "Test". b heeft een keertje naar "Test" gewezen, en nu verleg je hem naar "niet test".

    Quote Originally Posted by Tw33tst3r View Post
    This quote is hidden because you are ignoring this member. Show
    String type = "mountainbike";

    Fiets.setType(type);

    method heeft dan volgende body:
    Public void setType(String type){
    this.type = type;
    }
    Je moet weten dat type in de main method en type in de argumenten van je setType() method verschillende variabelen zijn. Op het moment dat je setType(type) aanroept, worden je actuele parameters (in dit geval type uit je main method) gekopieerd in de formele parameters (de type uit je argumenten). Je kunt zeggen dat in Java references op zich gekopieerd worden by value, terwijl de objecten zelf gekopieerd worden by reference.

    De reden waarom de property van je Fiets niet verandert als je type in je main nadien verandert, is omdat het veldje type van je Fiets niet dezelfde variabele is als type in je main method. Je laat die in de main method wijzen naar een andere String, maar die in je Fiets blijft ongewijzigd.

    En for the record: een String is een object, en die wrapper types (Integer, Double, ...) ook, en ze worden dus net als alle andere objecten by reference doorgegeven. De enige manier waarop ze verschillen van andere objecten is dat sommige instances gepoold/gecached worden.
    Last edited by forloRn_; 13-04-2010 at 11:47.
    no votes  

  5. #5
    Curahee Q's Avatar
    Registered
    07/12/07
    Location
    Hoogstraten
    Posts
    854
    iTrader
    0
    Mentioned
    0 Post(s)
    Een string in java is ook immutable (onveranderbaar). Dit wilt dus zeggen dat wanneer je dit zou doen

    Code:
    String foo="";
    for(int i=0; i<10; i++) {
            foo += Integer.toString(i) + " ";
    }
    Je bij de concatenatie telkens een nieuw object aanmaakt omdat je een string niet kan aanpassen. Met als gevolg dat wanneer je hier een oneindige lus van gaat maken je geheugen vol loopt. (Ik weet nu wel niet hoe regelmatig de garbage collector langskomt)

    -----------------------------------------------------------------------
    Even offtopic hoe je dit dan wel zou moeten doen
    Code:
    StringBuffer sb = new StringBuffer();
    for(int i=0; i<10; i++) {
             sb.append(Integer.toString(i)).append(" ");       // .append() returned to stringbuffer
    }
    
    String foo = sb.toString();
    -----------------------------------------------------------------------

    Als je dus zegt
    Code:
    String foo = "Test";
    String bar = foo;
    Dan heb je 2 referenties die naar een geheugenplaats verwijzen met de string Test

    foo ---------> Test <----------- bar

    Aangezien string immutable zijn gaat hij de string waar bar naar verwijst niet aanpassen maar een nieuwe maken en de verwijzing van bar verleggen

    Code:
    String foo = "Test";
    String bar = foo;
    
    bar = "Nieuw String-object"
    foo ---------> Test
    bar ---------> Nieuw String-object

    Echter wanneer je zoiets zou doen
    Code:
    Persoon foo = new Persoon("Jan");
    Persoon bar = foo;
    
    bar.setNaam("Jef");
    Zal door de setNaam de naam zowel bij foo als bij bar veranderen in Jef.
    no votes  

  6. #6
    NeverwinterX's Avatar
    Registered
    27/08/04
    Location
    Leuven
    Posts
    930
    iTrader
    0
    Mentioned
    0 Post(s)
    Reputation
    11/38
    Je lijkt een beetje het effect van het aanpassen van een object via een reference te verwarren met het effect van het toekennen van een nieuwe verwijzing.

    Voor de duidelijkheid stel:
    Code:
    public class Car {
    
    public int number = 0;
    
    }
    Dan:

    Code:
    Car a = new Car();
    Car b = a;
    b.number = 1;
    // het volgende print 1
    System.out.println(b.number);
    // het volgende print ook 1
    System.out.println(a.number);
    Dit komt omdat a en b allebei verwijzen naar hetzelfde Car object. Via b wijzig je het object waarnaar a ook verwijst.

    Maar:

    Code:
    Car a = new Car();
    a.number = 1;
    Car b = a;
    b = new Car();
    // het volgende print 0
    System.out.println(b.number);
    // het volgende print 1
    System.out.println(a.number);
    Dit komt omdat je b naar iets anders laat verwijzen nu. Na "b = new Car();" verwijst b naar een ander object dan naar waar a verwijst.

    Met String is dit niet verschillend. Het lijkt gewoon anders omdat java toelaat om:
    Code:
    char data[] = {'a', 'b', 'c'};
    String str = new String(data);
    te schrijven als:
    Code:
    String str = "abc";
    Last edited by NeverwinterX; 13-04-2010 at 15:03.
    no votes  

  7. #7
    Tw33tst3r's Avatar
    Registered
    08/06/03
    Location
    Opglabbeek
    Posts
    1,400
    iTrader
    0
    Mentioned
    0 Post(s)
    Reputation
    0/2
    ok thx, mensen nu snap ik het eindelijk, ik kon het wel juist toepassen (mijn vb was idd fout, maar dr leg ik de schuld van bij het late uur dak dit gepost heb )
    wel triestig dat een "docent" bij de vdab mij dit niet kan uitleggen
    no votes  

  8. #8

    Registered
    31/12/04
    Posts
    201
    iTrader
    1 (100%)
    Mentioned
    0 Post(s)
    Reputation
    0/0
    Nog een eenvoudig geheugensteuntje:

    In Java is elke parameter een waardeparameter. In het geval van niet primitieve variabelen/parameters is de waarde echter een referentie naar een object.
    Een computer die (meestal) werkt.
    no votes  

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

Log in

Log in