Object by Reference vs. Reference by Value

I read this comment here: Passing a String by Reference in Java?

Yes, it's a misconception. It's a huge, widespread misconception. It leads to an interview question I hate: ("how does Java pass arguments"). I hate it because roughly half of the interviewers actually seem to want the wrong answer ("primitives by value, objects by reference"). The right answer takes longer to give, and seems to confuse some of them. And they won't be convinced: I swear I flunked a tech screen because the CSMajor-type screener had heard the misconception in college and believed it as gospel. Feh. – CPerkins Aug 13 '09 at 14:34

Can someone please explain, in terms that a new programmer can grasp, what is the difference between saying:

"In Java primitives are passed by value and objects are passed by reference."

and:

"In Java nothing is passed by reference and references are passed by value."?

Are both of these statements true in some sense? I don't want to invite a rant parade, but this sounds like a really important concept, and one I still do not completely understand.


I believe the misconception lies in the fact that a variable can not contain an object to begin with. If you grasp that, then obviously variables can only contain references to objects (or primitive values). The step from there to realizing that references are passed by value (just as primitive values) is quite small.

There is a really easy test you can do to figure out if a language supports pass by reference. Ask yourself if you can write a swap function in the language, ie something that works like

x == A, y == B

swap(x, y);

x == B, y == A

As a Java programmer you realize quickly that you can't implement this in Java, thus you (correctly) draw the conclusion that Java does not have pass by reference.

Returning to your sentences:

  • In Java primitives are passed by value and objects are passed by reference.
  • This is false . I would argue that you can only pass something that is contained in a variable, and as I stated above, a variable can't contain an object, thus you can't pass an object at all in Java.

  • In Java nothing is passed by reference and references are passed by value.
  • This is true .


    Things like this are always easier when drawn. Consider the following two variables, one being a primitive-type and one being a reference-type:

        int i    = 5;
        String s = "test";
    

    somewhere in memory there is an entry for i that looks like this:

      i
    -----
    | 5 |
    -----
    

    similarly there is also an entry for s in memory but it refers to a location on the heap since s is a reference-type variable and objects are stored on the heap:

                                ----------- 
     s                 |------->|  "test" |
    -----              |        |---------|
    | --|--------------|        |         |
    -----                       |         |
                                |         |
                                |---------|
    

    So the value of s is the reference to that String object that is sitting on the heap, so if s were passed to a method:

    printString(s);
    
    public void printString(String arg)
    {
       System.out.println(arg);
    }
    

    The value that actually gets copied into the arg parameter is that reference to s on the heap:

                                ----------- 
     s                 |------->|  "test" |<-----|
    -----              |        |---------|      |
    | --|--------------|        |         |      |
    -----                       |         |      |
                                |         |      |
                                |---------|      |
     arg                                         |
    -----                                        |
    | --|----------------------------------------- 
    -----
    

    Hope this helps.


    Good question. Consider the following sample

    void foo(Object obj) {
      obj = new Foo(); 
    }
    
    Object o = new Bar();
    foo(o);
    // is o Foo or Bar?
    
  • If pass by-reference the o reference could have changed after calling foo
  • If pass by-reference-by-value the reference o is unchanged after calling foo
  • 链接地址: http://www.djcxy.com/p/20884.html

    上一篇: 返回字符串的方法

    下一篇: 按参考对象与按值参照