Monday, April 25, 2011

Java object reference/scope question

If I have a member variable such as this (declared in the body of a class)

private Dot[] dots=new Dot[numDots];

I loop through all members of this array, and:

1) Pass every Dot object to a function of another class, which:

2) Passes it to yet another function of a 3rd class, if some conditions are met

3) And the 3rd class changes some properties of the Dot object

then when this object is returned to the original/parent class, would those changes to its properties have retained? Or would it be treated like a local variable by the 2nd/3rd functions?

From stackoverflow
  • Yes, the changes to the properties are retained. Java is 100% pass-by-value, however, when you pass an object, the "value" passed is truly a pointer to the object. Thus, when you change an object in a method, you're changing the actual object passed in.

    That is, if you have the following method, then the calling method will see the changes:

    private void updateMyDot(final Dot aDot) {
      aDot.dotColor = new Color(255,255,255);
    }
    

    but if you do the following, then the calling method will not see the changes.

    private void updateMyDot(/* not final */ Dot aDot) {
      aDot = new Dot();
      aDot.dotColor = new Color(255,255,255);
    }
    

    In the second example, the caller will not see any changes and will not see the newly created Dot object.

  • Objects are passed by [reference value where the value is the reference] (things that inherit from Object), primitive values (int, long, double, etc.) are passed by value.

    This means that when a primitive is passed from a caller to method it is copied, whereas with an object a [value of the] reference is passed.

    Which in turn means that when an object is mutated by a method the caller sees those changes because it has a reference to the same object.

    Conversely when a method mutates a primitive the caller does not see the changes as the method is working on a copy.

    [reason for the edits]

    If Java had pass by reference then you could do this:

    Object x;
    
    x = new Integer(42);
    foo(x);
    System.out.println(x.getClass()); // pass by reference would have it print out java.lang.Float
    

    where foo is defined as:

    void foo(Object o)
    {
       o = new Float(43);
    }
    

    Since Java passes the reference by value "o = new Float(43);" is allowed - but the value in the caller will remain as the "new Integer(42);"

    mtruesdell : As stated in a million other places, this isn't strictly true. All parameters are passed by value in Java. However, object variables actually refer to object references. Passing an object as a method parameter copies the object variable, i.e. copies the reference.

0 comments:

Post a Comment