I have a question regarding passing parameters to a method. Can someone explain me why modifyParameters(Integer v1, Integer v2) doesn't change variables even they are passed as references are references to the objects.
Thanks, for quick and very useful answer. In fact I had known that parameters in java aren't passed as reference and I've used mistaken words to describe passing a reference (not as reference) to an object. Anyway this two sentences are what I was looking for
If the method changes its copy of the pointer to point to a different object the original pointer is not affected. If the method changes some of the attributes of the object, it changes the original object.
Mark Moge wrote:
Can someone explain me why modifyParameters(Integer v1, Integer v2) doesn't change variables even they are passed as references.
Actually, what you're doing in that method isn't quite what you're expecting, and it actually doesn't have anything to do with whether or not the objects are passed by reference. What you're actually doing is assigning a new object to the v1 and v2 parameters, so that they're no longer referring to the original objects that were passed in. If you did something like this instead:
That would be closer to what you're expecting, and it would also help explain the difference between pass-by-value and pass-by-reference (at least as I understand it). If Java passed parameters by values, it would create a copy of the object to pass into the method, and you could do whatever you wish to it without having any effect on anything outside of your method:
With passing an object reference to a method, the method has access to the original object itself, and not just a copy of it. In your original code, however, you reassigned the parameters/variables v1 and v2 so that they were no longer pointing at their original objects, but were pointing to the new Integer objects you created.
As a side note, you've probably noticed I've used the "final" keyword on my parameter declarations. The purpose of that is to avoid the exact situation you've come across -- you'll get a compiler error if you try to assign to a parameter that's declared final. That way there's not even a chance that someone comes along and thinks they can modify the object in that way, because 99% of the time it won't be what they're expecting.
I actually had one of my coworkers here -- a really smart guy -- run into this himself the other day and had to explain it there also, so you're not alone ;)
Thanks -- and while that was my first post, I've visited the ranch many times over the years; always seems to come up in a google search at least once a day
You're right about autoboxing of course; I honestly hadn't thought to include that in the explanation, but it is definitely something that's always worth considering when working with primitives and wrappers.
Another aspect that I'd meant to mention and forgot about was that the wrapper classes -- such as Integer -- and a few other JDK library classes (String is the main one that comes to mind) are immutable, which is another reason why passing by reference doesn't help matters -- the object's internal data can't be changed anyways. By contrast, the (albeit contrived) class I used is mutable, so its internal data can change. Immutable objects in this case are kinda like passing by value, without the added overhead of creating a copy of the object.
(Getting into all the intricacies of mutability/immutability and passing by reference is probably worthy of a book in it's own, or at least it's beyond the scope of this discussion I imagine, unless someone else has more specific scenarios to work with...)
Paul Clapham wrote:Just one additional comment -- because Mark chose Integer for the type of object
I have used Integer instead of int because I thought that reference to it allows to modify the object (and couldn't understand why it didn't work). But it turned out that copy of the reference passed as input parameter was assigned to another object.
Matthew Cory wrote:Another aspect that I'd meant to mention and forgot about was that the wrapper classes -- such as Integer -- and a few other JDK library classes (String is the main one that comes to mind) are immutable
Even the Integer class is immutable, in this case, assigning different Integer object with new value would be ok if you need just a value of it. But as it was explained earlier, method uses copy of the reference which doesn't have any effect on the orginal object, because points to the diffrent one :)