Please advice why primitives being used as method's parameters do a copy of its value while objects are used as is?
In Java, all arguments are passed by value - but in the case of reference types (i.e. everything other than a primitive) the value of a variable isn't the object itself - it's a reference to the object. Thus that reference is copied into the method's parameter, so it refers to the same object.
Note that this doesn't just apply to method calls:
StringBuilder x = new StringBuilder();
StringBuilder y = x; // Copy the value of x, which is a *reference*
y.append("Hello");
System.out.println(x); // Prints "Hello"
Here, x
and y
refer to the same object, even though they're separate variables. Thus when the contents of that object is changed via the append
call through the y
variable, the change is visible via the x
variable too.
I think of it as being a bit like giving someone the address of your house: if I give two people my home address, and one of them paints the door red, then when the second person visits the house, they'll see the red door too. I'm not giving them my house itself, I'm giving them a way of getting to my house.
There are many, many articles about this - although unfortunately some will claim that objects are passed by reference in Java. They're not - the references are passed by value, as I said above. Scott Stanchfield has a good article about this, amongst many others.
To expand on what Jon Skeet said, primitive types are usually quite small - a double is 8 bytes. Objects, on the other hand, can be HUGE, and so passing a reference to them saves time and stack space versus copying the whole thing. Plus this allows you to modify the contents of the Object.
That's what it looks like but is not. Java is always pass by value.
When you declare something like this:
Date aDate = new Date();
The variable aDate
is not really an object, but an object reference. When you pass that object reference to another method, a "copy" of that reference is passed ( just like with primitives a copy of the value is passed )
Now, since those two copies "reference" the same underlaying object, you see that sending a message on one of them affects the other, but if you change the reference to assign a new one, the other doesn't change.
For instance:
class Some {
int data = 0;
}
class Other {
void doSomething( Some o ) {
o.data = 10;
}
void change( Some a ) {
a = new Some();
a.data = 1024;
}
}
class Main {
public static void main( String [] args ) {
// create an object and get its object reference
Some original = new Some();
System.out.println( original.data ); // prints 0
// now pass it to a method from the class "Other"
Other o = new Other();
other.doSomething( original );
System.out.println( original.data ); // prints 10, because data was changed in "doSomething"
// To probe that the reference is not passed, but a copy of it
// invoke the "change" method.
other.change( original );
System.out.println( original.data ); // remains 10, instead of 1024.
// the value 1024 was changed in the new reference, and the one passed along
// didn't change. It still refers to the original object.
}
}
I hope this helps