1

In java all methods are pass by value.But today i learnt that constructors are pass by reference.

// Attack the internals of a Period instance
Date start = new Date();
Date end = new Date();
Period p = new Period(start, end);
end.setYear(78);  // Modifies internals of p!

This works and is able to edit the private fields.

What is the reason of this decision? or am i missing something?

Salih Erikci
  • 5,076
  • 12
  • 39
  • 69

5 Answers5

8

You've got that wrong:

In java all methods are pass by value.

Instead: In Java all parameters are passed by value, even references are passed by value.

You don't "pass objects", only references to objects. This is the same for methods and constructors.

So

end.setYear(78);  // Modifies internals of p!

does not change the reference but only the object the reference points to.

A.H.
  • 63,967
  • 15
  • 92
  • 126
3

It will work same way for other method. Actually reference is passed by value.

Class A{
   B b;
   void setB(B b) {
       this.b = b;
   }
};

A a;
B b;
A.setB(b);

b.change(); //changed in A

What it means that reference is passed by value?

void f(A a) {
    a.change(); // caller will see that object is changed. We change it using reference
    a = new A(); // we change the value of refernce. No changes are visible outside the function
    a.change(); //new object is changing. No changes are visible outside the function
}

Basically you just pass address of object (integer) by value. Everything is integer. Your class contains integer. And it didn't change. The objects on that address did.

RiaD
  • 46,822
  • 11
  • 79
  • 123
  • +1 for nice example. As a side note, some people don't realise you can declare parameters final i.e. `f(final A a){ ... }` this ensures that you don't inadvertently override a - not that this is very relevant to this discussion. – selig Jul 13 '13 at 10:53
1

the mechanism is same for both constructor and method. From the doc

Reference data type parameters, such as objects, are also passed into methods by value. This means that when the method returns, the passed-in reference still references the same object as before. However, the values of the object's fields can be changed in the method, if they have the proper access level

stinepike
  • 54,068
  • 14
  • 92
  • 112
1

No, you aren't changing any private fields. The private fields in Period are not touched, they still reference the same object. Unfortunatly, a Date object is mutable. So you see the mutation through the Period object.

If you want to avoid this, make a copy of each object passed in the constructor, only thus you'll have your own Date objects no one outside of Period can modify.

Ingo
  • 36,037
  • 5
  • 53
  • 100
0

You are dealing with only references,not objects.

The classic definition of pass by value.

The value of a reference variable is an "address" in Java. When you pass a reference variable to a method, a new reference variable is placed on the stack and a copy of the passed reference variable's value is used to initialize the new local reference varaible's value, just like any primitive type.

NOTE: While you can think of the reference as a memory address, it's not. The underlying mechanism makes it act logically as if it were though.

SHORT VERSION: references are simple variables just like the other primitive types for purposes of passing arguments to methods. What you can do with them once passed is obviously different.

Suresh Atta
  • 120,458
  • 37
  • 198
  • 307