pass by reference

Discussion in 'Java' started by angelochen960@gmail.com, Apr 4, 2008.

  1. Guest

    Hi,

    what is the equivalent of Java approach to this C++ function:

    public void myFunc(String &s) {
    s = "123";
    }

    I'd like to define a method where several values can be returned. any
    idea?

    Angelo
     
    , Apr 4, 2008
    #1
    1. Advertising

  2. Donkey Hot Guest

    "" <> wrote in news:6f782877-
    :

    > Hi,
    >
    > what is the equivalent of Java approach to this C++ function:
    >
    > public void myFunc(String &s) {
    > s = "123";
    > }
    >
    > I'd like to define a method where several values can be returned. any
    > idea?
    >
    > Angelo
    >
    >


    public void myFunc(String s) {
    s = "123";
    }

    In java, all objects are passed by reference.

    Basic data types like int, long, boolean are passed by value. Object
    variables are always references to an object, and the reference is passed
    "by value" as the basic data types, but it is a reference, so...
     
    Donkey Hot, Apr 4, 2008
    #2
    1. Advertising

  3. Roedy Green Guest

    Roedy Green, Apr 4, 2008
    #3
  4. Roedy Green Guest

    On Thu, 3 Apr 2008 23:07:50 -0700 (PDT), ""
    <> wrote, quoted or indirectly quoted someone
    who said :

    >I'd like to define a method where several values can be returned. any
    >idea?


    1. you pass in an object, and you set fields on that object.

    2. you create a new object with several fields and return that.

    You can't change any of your caller's variables, just the fields in
    the objects they point to.

    --

    Roedy Green Canadian Mind Products
    The Java Glossary
    http://mindprod.com
     
    Roedy Green, Apr 4, 2008
    #4
  5. Guest

    Donkey Hot <-a-geek.com> wrote:

    > public void myFunc(String s) {
    > s = "123";
    > }


    This won't work, though. While the String object s' is passed by reference,
    the _reference_ s is passed by value. Any changes made to the reference in
    the subprogram -- such as changing the object it points to -- will not have
    any effect on the main program.

    public class Demo {
    private static final STRING_1 = "String_1";
    private static final STRING_2 = "String_2";

    public void outer( ) {
    String workString = STRING_1;
    change( workString );
    // workString is still pointing to STRING_1
    }

    public void change( String stringToChange ) {
    stringToChange = STRING_2;
    }
    }

    If the argument is a mutable type (unlike String), you can get the required
    effect by modifying (rather than reassigning) the object:

    public class Demo2 {
    private static final STRING_1 = "String_1";
    private static final STRING_2 = "String_2";

    public void outer( ) {
    StringBuffer workString = new StringBuffer( STRING_1 );
    change1( workString );
    // workString now equals "String_2"
    change2( workString );
    // workString _still_ equals "String_2"
    }

    public void change1( StringBuffer stringToChange ) {
    stringToChange.delete( 0, stringToChange.length( ) );
    stringToChange.append( STRING_2 );
    }

    public void change2( StringBuffer stringToChange ) {
    // This won't work, as the change to the reference is
    // lost when the method returns
    stringToChange = new StringBuffer( STRING_1 );
    }
    } // end class


    If you have an immutable type or need to create a whole new object for some
    other reason, you'll need to use some kind of wrapper. Either a
    data-structure or an array:

    public void change( String[] stringWrapper ) {
    stringWrapper[0] = STRING_2;
    }


    private static final class ChangeData {
    public String toBeChanged;
    }

    public void change( ChangeData data ) {
    data.toBeChanged = STRING_2;
    }

    --
    Leif Roar Moldskred
    Got Sfik?
     
    , Apr 4, 2008
    #5
  6. All objects are "passed by reference" and all primitive types have
    their value copied.
     
    Chase Preuninger, Apr 4, 2008
    #6
  7. Roedy Green wrote:
    > On 04 Apr 2008 06:14:40 GMT, Donkey Hot <-a-geek.com>
    > wrote, quoted or indirectly quoted someone who said :
    >
    >> In java, all objects are passed by reference.

    >
    > Nope. By value. See http://mindprod.com/jgloss/callbyvalue.html


    Roedy is right, also a reference is passed by value.

    void foo(Object ref) {
    ref = b; // affect the sole method
    }

    Object ref = a; // ref points to same object that 'a' points.
    foo(ref);
    assert(ref==a); // ref still point to same object that 'a' points.

    --
    Andrea Francia
    http://www.andreafrancia.it/
     
    Andrea Francia, Apr 4, 2008
    #7
  8. Stefan Ram Guest

    "" <> writes:
    >I'd like to define a method where several values can be
    >returned. any idea?


    According to the JLS, methods are »declared«.

    »You can't return more than one value from a method. If
    you want to, you have to return a little array (unless one
    value is an int and the other is a Person!) or an object
    of some special little class made just for this purpose.
    When I was helping Bill Joy and Guy L. Steele Jr. by
    reviewing drafts of the original Java Language
    Specification, I was originally upset that there was no
    way to do this. So I set out to find a small example
    program that obviously demanded such a feature, to
    convince them that multiple value returns must be added. I
    was unable to come up with one, and I could see that
    Java's philosphy was to leave out things that are rarely
    used and not crucial, so finally didn't say anything.«

    Dan Weinreb's Weblog

    http://dlweinreb.wordpress.com/category/java/

    I have written several programs myself to show how multiple
    returns might be emulated in Java. Each approach has its
    advantages and disadvantages. I might add that, whenever I
    want to achieve something with Java, the lack of explicit
    multiple return values is not a problem for me.

    So, here are my notes:

    I assume a simple multiple-return task such as, in pseudocode:

    operation "sumdiff"
    in x, y;
    out sum, difference;
    { sum = x + y; difference = x - y; }

    Solution with public fields:

    class Sumdiff
    { public Sumdiff( final int x, final int y )
    { this.sum = x + y; this.difference = x - y; }
    public final int sum; public final int difference; }

    public class Main
    { public static void main( final java.lang.String[] args )
    { final Sumdiff result = new Sumdiff( 4, 2 );
    java.lang.System.out.println
    ( result.sum + ", " + result.difference ); }}

    6, 2

    If you do not like public fields, you might use getters
    as well.

    A »processor object« can be created once and be used
    several times:

    public class Main
    { public static void main( final java.lang.String[] args )
    { final Processor processor = new Processor();
    processor.set( 4, 2 );
    processor.calculateSumDiff();
    java.lang.System.out.println( processor.getSum() );
    java.lang.System.out.println( processor.getDifference() );
    processor.set( 8, 4 );
    processor.calculateSumDiff();
    java.lang.System.out.println( processor.getSum() );
    java.lang.System.out.println( processor.getDifference() ); }}

    class Processor
    { public void set( final int x, final int y )
    { this.x = x; this.y = y; }
    public void calculateSumDiff()
    { this.sum = x + y; this.difference = x - y; }
    public java.lang.Integer getSum(){ return sum; }
    public java.lang.Integer getDifference(){ return difference; }
    int x; int y; int sum; int difference; }

    To avoid allocation overhead of a result object,
    the client might provide and reuse such an object:

    class Result { public int x; public int y; }

    class Server
    { void run( final Result result, final int x, final int y )
    { result.x = x + y; result.y = x - y; }}

    public final class Main
    { private static Result result = new Result(); /* single allocation */
    public static void main( final java.lang.String argv[] )
    { Server server = new Server();
    server.run( result, 1, 2 );
    java.lang.System.out.println( result.x );
    java.lang.System.out.println( result.y );
    server.run( result, 3, 4 );
    java.lang.System.out.println( result.x );
    java.lang.System.out.println( result.y ); }}

    One can also emulate multiple returns via multiple
    arguments, but only when adopting a »continuation passing
    style«. In the next example, the server »returns« a pair
    of random numbers to the client, by calling back a method
    provided by the client.

    interface Client { void continuation( int x, int y ); }

    class Server
    { static java.util.Random rand = new java.util.Random();
    static void getPair( final Client client )
    { client.continuation( rand.nextInt( 11 ), rand.nextInt( 21 )); }}

    class Example implements Client
    { public void continuation( final int x, final int y )
    { java.lang.System.out.println( x + ", " + y ); }
    public void main()
    { Server.getPair( this ); }}

    public class Main
    { public static void main( final java.lang.String[] args )
    { new Example().main(); }}

    But, as said, I rarely ever (actually: never) have needed any
    of these multiple return value emulations in my own projects.

    Possibly this is because I already have accounted for the
    properties and limitations of Java when I was designing
    my classes. So I have designed them from the start in such
    a way that multiple return values are not needed.
     
    Stefan Ram, Apr 4, 2008
    #8
  9. Chase Preuninger <> wrote:
    > All objects are "passed by reference" and all primitive types have
    > their value copied.


    The objects are indeed passed by reference.

    There is a fundamental difference between C++ and Java
    with respect to the assignment-operator.

    In C++, assignment is the Object's business,
    so, passing an object into a function and assigning
    to it inside, will change the value of that object,
    and thus be visible outside.

    In Java, assignment (with "="-operator) does not
    change the referenced Object, but replace it, by
    changing only the reference.
    This effect, however, is not visible outside,
    because it's only the Object, but not the reference
    itself, that is passed "by ref".
     
    Andreas Leitgeb, Apr 4, 2008
    #9
  10. Lew Guest

    Chase Preuninger wrote:
    > All objects are "passed by reference" and all primitive types have
    > their value copied.


    As others have stated and illustrated in this thread, that is not actually
    accurate. That's why those quote marks, presumably.

    In the sense that C++ programmers use "reference", Java objects are passed by
    value, and the official word in Java is that references are passed by value
    just as primitives are.

    In any event, reassigning the formal parameter within a method does not change
    the reference passed from the caller's point of view.

    Stefan Ram provided good examples of idioms to handle the OP's need.

    --
    Lew
     
    Lew, Apr 4, 2008
    #10
  11. Lew Guest

    Andreas Leitgeb wrote:
    > Chase Preuninger <> wrote:
    >> All objects are "passed by reference" and all primitive types have
    >> their value copied.

    >
    > The objects are indeed passed by reference.


    When I took a practice certification exam in Java, I was marked wrong for
    saying that objects are passed by reference. The fact is that objects are not
    passed at all - references are, and they are passed by value.

    --
    Lew
     
    Lew, Apr 4, 2008
    #11
  12. Lew <> wrote:
    > Andreas Leitgeb wrote:
    >> Chase Preuninger <> wrote:
    >>> All objects are "passed by reference" and all primitive types have
    >>> their value copied.

    >> The objects are indeed passed by reference.

    > When I took a practice certification exam in Java, I was marked wrong for
    > saying that objects are passed by reference. The fact is that objects are not
    > passed at all - references are, and they are passed by value.


    This indication of lingual hairsplitting perhaps explains, why I got
    somewhat less than 100% for my SCJP (but still by far enough to pass).
    Can't say for sure, since one is never told, which of the questions
    were really answered wrongly.

    Just as well one could say that nothing at all is passed (since methods
    don't have arms or hands to pass things around), but only written to some
    physical memory-location where it is then accessible to the called method...
    and then we go on, that the jvm doesn't really "call" the method, because
    the method doesn't have ears to hear any calling...(btw., "invoke" also has
    an etymology that boils down to some form of akoustic communication.)
    Really, this makes me sick.
     
    Andreas Leitgeb, Apr 4, 2008
    #12
  13. Andreas Leitgeb wrote:
    > Lew <> wrote:
    >> Andreas Leitgeb wrote:
    >>> Chase Preuninger <> wrote:
    >>>> All objects are "passed by reference" and all primitive types have
    >>>> their value copied.
    >>> The objects are indeed passed by reference.

    >> When I took a practice certification exam in Java, I was marked wrong for
    >> saying that objects are passed by reference. The fact is that objects are not
    >> passed at all - references are, and they are passed by value.

    >
    > This indication of lingual hairsplitting perhaps explains, why I got
    > somewhat less than 100% for my SCJP (but still by far enough to pass).
    > Can't say for sure, since one is never told, which of the questions
    > were really answered wrongly.
    >
    > Just as well one could say that nothing at all is passed (since methods
    > don't have arms or hands to pass things around), but only written to some
    > physical memory-location where it is then accessible to the called method...
    > and then we go on, that the jvm doesn't really "call" the method, because
    > the method doesn't have ears to hear any calling...(btw., "invoke" also has
    > an etymology that boils down to some form of akoustic communication.)
    > Really, this makes me sick.
    >


    I don't think this one is just hairsplitting. The "objects passed by
    reference" model does not explain what happens when the actual argument
    is a null reference. The actual behavior matches nicely the behavior
    that predicted by the "references passed by value" model.

    More generally, the "references passed by value" fits well with the
    general observation that non-primitive expressions are all possibly-null
    references, not objects. The actual argument is just a reference expression.

    Patricia
     
    Patricia Shanahan, Apr 4, 2008
    #13
  14. Guest

    Hi guys,

    Thanks for all the answers, I'm kind of surprised that a simple
    question got so many answers! is this statement correct:

    Everything in Java are passed by value, in the case of an object, a
    reference to the object is passed, which is a value too, updating the
    fields in the reference does reflect the changes. anyway, maybe I
    should not try to understand java in a C++ manner.

    but i can't help, String is a object, so a reference should be the one
    passed, and why we can not update the field in the String object? and
    then where is the field of the String?


    Angelo


    On Apr 4, 9:21 pm, Patricia Shanahan <> wrote:
    > Andreas Leitgeb wrote:
    > > Lew <> wrote:
     
    , Apr 4, 2008
    #14
  15. Donkey Hot Guest

    "" <> wrote in news:0a4ad57b-
    :

    > Hi guys,
    >
    > Thanks for all the answers, I'm kind of surprised that a simple
    > question got so many answers! is this statement correct:
    >
    > Everything in Java are passed by value, in the case of an object, a
    > reference to the object is passed, which is a value too, updating the
    > fields in the reference does reflect the changes. anyway, maybe I
    > should not try to understand java in a C++ manner.
    >
    > but i can't help, String is a object, so a reference should be the one
    > passed, and why we can not update the field in the String object? and
    > then where is the field of the String?
    >
    >


    Yes, I was wrong in my

    public void myFunc(String s) {
    s = "123";
    }

    because that compiles exactly as

    public void myFunc(String s) {
    s = new String("123");
    }


    If the String class had a method setValue() we could write

    public void myFunc(String s) {
    s.setValue("123");
    }

    but it does not, and we can't.

    Some kind of a wrapper class is needed with the methods required.
     
    Donkey Hot, Apr 4, 2008
    #15
  16. Guest

    <> wrote:
    > Hi guys,
    >
    > Thanks for all the answers, I'm kind of surprised that a simple
    > question got so many answers! is this statement correct:
    >
    > Everything in Java are passed by value, in the case of an object, a
    > reference to the object is passed, which is a value too, updating the
    > fields in the reference does reflect the changes. anyway, maybe I
    > should not try to understand java in a C++ manner.


    Think of it like this: Java has two different types of arguments,
    fundamental values and references (similar to "smart pointers" in C++
    terms). Both of these are copied by value.

    Let's say you make the following two declarations:

    int aNumber = 15;
    String aString = "Hey!";

    This will create three things in memory: an int with the value 15, a String
    object with the value "Hey!" and a reference to the string object. Let's say
    these are stored in memory addresses 0x1000, 0x2000 and 0x3000 respectively:

    0x1000: 15
    0x2000: "Hey!"
    0x3000: ->0x2000

    If you now make a call to a subroutine:

    doStuff( aString, aNumber );

    Local copies will be made of the int and of the reference, but not of the
    object. Let's say these local copies are stored in 0x4000 and 0x5000:

    0x1000: 15
    0x2000: "Hey!"
    0x3000: ->0x2000
    0x4000: ->0x2000
    0x5000: 15

    If doStuff( ) looks like this, just before the method returns we'll have the
    situation below:

    private void doStuff( String aString, int aNumber ) {
    aString = "Hello!";
    aNumber = 20;
    }

    0x1000: 15
    0x2000: "Hey!"
    0x3000: ->0x2000
    0x4000: ->0x6000
    0x5000: 20
    0x6000: "Hello!"

    Then, once the local variables have been reclaimed, we'll be back to this:

    0x1000: 15
    0x2000: "Hey!"
    0x3000: ->0x2000

    (Well, 0x6000 will still contain the "Hello!" string until the next run of
    the garbage collector, but we have no way of making use of it.)


    --
    Leif Roar Moldskred
     
    , Apr 4, 2008
    #16
  17. wrote:

    Top-posting re-ordered - please don't top-post.

    >
    > On Apr 4, 9:21 pm, Patricia Shanahan <> wrote:
    >> Andreas Leitgeb wrote:
    >>> Lew <> wrote:

    >
    >
    > Thanks for all the answers, I'm kind of surprised that a simple
    > question got so many answers! is this statement correct:
    >
    > Everything in Java are passed by value, in the case of an object, a
    > reference to the object is passed, which is a value too, updating the
    > fields in the reference does reflect the changes.


    Its sort of correct but the language is a bit sloppy and open to
    misinterpretation.


    > anyway, maybe I
    > should not try to understand java in a C++ manner.


    I think you shouldn't. People who do seem to get confused.


    > but i can't help,


    Oh dear.


    > String is a object,


    Yes

    > so a reference should be the one passed,


    Yes, well a copy of the reference is passed.


    > and why we can not update the field in the String object?


    1) Strings don't have any public fields of the sort you imply.
    2) Strings are immutable by definition.

    Not all objects are immutable (obviously) but Strings are, by intention.


    > and then where is the field of the String?


    This isn't a meaningful question.


    Consider ...
    main() {
    String x = "aaa";
    foo(x);
    }
    static void foo(String s) {
    String p = s; // ONE
    s = "bbb" // TWO
    }

    There is an object of class String, having been instantiated it exists
    somewhere in memory. Within this chunk of memory is (presumably) the
    UCS-2 representation of the characters "aaa".

    Just before assignment TWO there are at least three references that
    "point" to this object. These three references have three names (x, s
    and p). We can say that variables x,s and p contain a reference to the
    same object. However s is a copy of x it isn't a reference or pointer to x.

    If I were writing a JVM I might have structures not entirely unlike like
    this:

    After assignment "ONE":

    addr contents

    000 "x" 122 "s" 177 "p" 127
    044 3 "aaa"
    122 44
    127 44
    177 44

    After assignment "TWO":

    000 "x" 122 "s" 177 "p" 127
    044 3 "aaa"
    122 44
    127 44
    177 251
    251 3 "bbb"

    Notice that changing what s points to has no effect on what x points to.

    I expect everyone will be glad I am not writing a JVM.


    --
    RGB
     
    RedGrittyBrick, Apr 4, 2008
    #17
  18. Wayne Guest

    Andrea Francia wrote:
    > Roedy Green wrote:
    >> On 04 Apr 2008 06:14:40 GMT, Donkey Hot <-a-geek.com>
    >> wrote, quoted or indirectly quoted someone who said :
    >>
    >>> In java, all objects are passed by reference.

    >>
    >> Nope. By value. See http://mindprod.com/jgloss/callbyvalue.html

    >
    > Roedy is right, also a reference is passed by value.


    Roedy is always right (almost). But I would state this differently:
    objects are not passed at all in Java, and everything else
    (including references to objects) is passed by value.

    -Wayne
     
    Wayne, Apr 4, 2008
    #18
  19. Mark Space Guest

    wrote:
    > Hi,
    >
    > what is the equivalent of Java approach to this C++ function:
    >
    > public void myFunc(String &s) {
    > s = "123";
    > }
    >
    > I'd like to define a method where several values can be returned. any
    > idea?



    While a lot of the discussion here is pretty good, I think it missed the
    fundamental point of giving the OP a simple answer.


    public void myFunc( String [] sa )
    {
    sa[0] = "123";
    }

    In Java, all primitives are passed by value, as has been much discussed.
    So you have to create a reference yourself, because there is is no
    pass by reference available.

    The most common pattern is just to use an array to pass the object
    reference. The reference can then be replaced with another reference
    and processed by the caller.

    public static void main( String [] args )
    {
    String sb[] = { "456" };
    myFunc( sb );
    System.out.println( sb[0] );
    }

    It's a little hokey, but it works. Well except for the static context
    ..... make myFunc static for this example.

    Not compiled....
     
    Mark Space, Apr 4, 2008
    #19
  20. Roedy Green Guest

    On Fri, 4 Apr 2008 03:37:55 -0700 (PDT), Chase Preuninger
    <> wrote, quoted or indirectly quoted someone
    who said :

    >All objects are "passed by reference" and all primitive types have
    >their value copied.


    The JLS is very clear on that. There is NO pass by reference in java.
    Patricia argued persuasively some time ago why we should not muddle
    the issue with talk of passing "objects by reference".

    You can't pass objects in Java. You can in C, actually pushing the
    entire object's contents to the stack.

    In Java, you can pass a reference by value, however.

    see http://mindprod.com/jgloss/callbyreference.html
    http://mindprod.com/jgloss/callbyvalue.html


    --

    Roedy Green Canadian Mind Products
    The Java Glossary
    http://mindprod.com
     
    Roedy Green, Apr 4, 2008
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jerry
    Replies:
    20
    Views:
    7,951
    Roedy Green
    Sep 9, 2005
  2. blufox
    Replies:
    2
    Views:
    564
  3. Mr A
    Replies:
    111
    Views:
    2,129
  4. Robert
    Replies:
    10
    Views:
    1,370
    E. Robert Tisdale
    Aug 24, 2005
  5. LuB
    Replies:
    6
    Views:
    456
    Mike Wahler
    Sep 23, 2005
Loading...

Share This Page