What exactly does “pass by reference” mean?

后端 未结 8 2119
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-30 03:15

And who has the authority to decide?

Edit: Apparently I haven\'t succeeded in formulating my question well.
I am not asking how Java\'s

相关标签:
8条回答
  • 2020-12-30 04:09

    If you are familiar with C, perhaps the following analogy explains how Java works. This will be true only for objects of class-type (and not fundamental type).

    In Java, we can have a variable and pass it to a function:

    void f(Object x)
    {
      x.bar = 5;    // #1j
      x = new Foo;  // #2j
    }
    
    void main()
    {
      Foo a;
      a.bar = 4;
      f(a);
      // now a.bar == 5
    }
    

    In C, this would look as follows:

    void f(struct Foo * p)
    {
      p->bar = 5;                      // #1c
      p = malloc(sizeof(struct Foo));  // #2c
    }
    
    int main()
    {
      struct Foo * w = malloc(sizeof(struct Foo));
      w->bar = 4;
      f(w);
      /* now w->bar = 5; */
    }
    

    In Java, variables of class-type are always references, which in C would be most faithfully mapped to pointers. But in function calls, the pointer itself is passed by copy. Accessing the pointer as in #1j and #1c modifies the original variable, so in that sense you are passing around a reference to the variable. However, the variable itself is only a pointer, and it itself is passed by copy. So when you assign something else to it. as in #2j and #2c, you are only rebinding the copy of the reference/pointer in the local scope of f. The original variable, a or w in the respective examples, remains untouched.

    In short: Everything is a reference, and references are passed by value.

    In C, on the other hand, I could implement a true "passing by reference" by declaring void v(struct Foo ** r); and calling f(&w); this would allow me to change w itself from within f.

    Note 1: this is not true for fundamental types like int, which are wholly passed by value.

    Note 2: A C++ example would be a bit tidier since I could pass the pointer by reference (and I didn't have to say struct): void f(Foo * & r) { r = new Foo; } and f(w);.

    0 讨论(0)
  • 2020-12-30 04:20

    Both of your C examples actually demonstrate pass-by-value, because C doesn't have pass-by-reference. It's just that the value that you're passing is a pointer. Pass-by-reference occurs in languages such as Perl:

    sub set_to_one($)
    {
        $_[0] = 1; # set argument = 1
    }
    my $a = 0;
    set_to_one($a); # equivalent to: $a = 1
    

    Here, the variable $a is actually passed by reference, so the subroutine can modify it. It's not modifying some object that $a is pointing to via indirection; rather, it modifies $a itself.

    Java is like C in this respect, except that in Java objects are "reference types", so all you ever have (and all you can ever pass) are pointers to them. Something like this:

    void setToOne(Integer i)
    {
        i = 1; // set argument = 1
    }
    
    void foo()
    {
        Integer a = 0;
        setToOne(a); // has no effect
    }
    

    won't actually change a; it only reassigns i.

    0 讨论(0)
提交回复
热议问题