Look at the "doStuff" method. "B = new Cat();" Remember what that means? B has it's bit of paper wiped and a new address (reference, bit pattern, call it what you will) written on it. This points at a new Cat on the heap.
A is still pointing at the old Cat. A's bit of paper (address/reference/bit pattern) has not been changed.
Try as I might I cannot get this question answered, and I think it is the key to the entire confusion for me:
In the method doStuff, B is just the parameter is it not? A is getting passed to it. So when you say that B has it's bit of paper wiped and a new address aren't we really talking about A? Because then you say A is still pointing at the old Cat. So I will ask again, there is an A (passed as an argument to the method to act as the B parameter) pointing to a new Cat, but then you say A is still pointing to the new Cat?
Am I confused about the method scope? Is it because A in the doStuff method goes out of scope?
A is not passed to it...... Only the copy of the bitpattern held in A is passed to B. THat's all
1 more thing pointing is a C++ word...Its double edged.Say A is referencing. If you refer your friend for a job in your company.But During the interview he is refered by a Different person. will your reference go off.
Can you wind your mind back to last night? Or was it all the wine? We thought you had it then; I think all these "bit patterns" have just confused you.
You have a Cat in your first method, which lives in memory at location 1234abcd (well, it might). So when you get to "A" you have
1234abcd <---- if you look in memory location 1234abcd you will find all the details of Cat "A".
on top of your stack (and lots of other numbers before it). Now you pass that cat to the doStuff method, so you have references on the stack to doStuff, then you pass the location of the cat object. Your stack will look something like this
1234abcd
xxxxxxxx
ijkijkij
xyzxyzxy
1234abcd
Look, your Cat "A" has reappeared. This is what Fred was on about last night, telling you about stack pointers. This is what it means by "pass-by-value". Your value is the location where you can find an object, and you see it has been passed onto the stack, as a copy. There are two references to your Cat on the stack, one which you called "A" and the JVM takes a copy of it, and you are calling this copy "B" in the doStuff method.
Now you tell your doStuff method to replace the Cat with another cat, which might be at memory location 2345bcde (it probably isn't, but in Java there is no way to prove that!). You take the original cat location off the stack and it now looks more like this
1234abcd
xxxxxxxx
ijkijkij
xyzxyzxy
2345bcde <---- The details of the new Cat are in memory location 2345bcde
You now manipulate your 2345bcde cat, and when your method finishes, Fred's stack pointer goes back, and your stack looks like this
1234abcd <---- pointer how here.
xxxxxxxx
ijkijkij
xyzxyzxy
2345bcde
Lo and behold, you forget everything struck through, and your original Cat has reappeared. That is 1234abcd. The same cat you had before. Your 2345bcde Cat has gone out of scope and next time you write anything on the stack all memory of where that cat was will vanish for ever.
I passed a Cat no 1 to doStuff, replaced it with Cat No 2 in the method, then when I got back to the original method, Cat No 1 was still there.
I got your phone number, and it was swapped for Joanne's phone number, but your phone number didn't change.
***************************************************************************************************************************************
If Java supported pass-by-reference (but it doesn't) you would be able to change the stack so it looks like this
2345bcde <---- pointer how here.
xxxxxxxx
ijkijkij
xyzxyzxy
2345bcde
But Java doesn't, so you can't change it like that.
Beware of thinking Java is an extension of C/C++. It is not; it is a completely different language. There are similarities in syntax, but they hide great differences. I think C++ supports pass-by-reference, C doesn't support it but allows you to mimic it. Java doesn't. It's different.
Look at the "doStuff" method. "B = new Cat();" Remember what that means? B has it's bit of paper wiped and a new address (reference, bit pattern, call it what you will) written on it. This points at a new Cat on the heap.
A is still pointing at the old Cat. A's bit of paper (address/reference/bit pattern) has not been changed.
Try as I might I cannot get this question answered, and I think it is the key to the entire confusion for me:
In the method doStuff, B is just the parameter is it not? A is getting passed to it. So when you say that B has it's bit of paper wiped and a new address aren't we really talking about A? Because then you say A is still pointing at the old Cat. So I will ask again, there is an A (passed as an argument to the method to act as the B parameter) pointing to a new Cat, but then you say A is still pointing to the new Cat?
Am I confused about the method scope? Is it because A in the doStuff method goes out of scope?
Scope is irrelevant to this problem.
Assume Cat overrides toString and prints the name of the cat.
Both A and B are in the same scope at all times. Passing the value of A to another method is not any different then the above example
The output would be:
The only thing that matters is the bit pattern stored in memory that represents A and B. Hopefully it is clear that the objects that reside at 0x0a and 0x10 and 0x14 are not the same object, even if the cat name is the same. Another good lesson is even if an overriden equals() or implemented compareTo() return true, that does not mean that the 2 references being compared both point to the same object.
Cat A = new Cat();
doStuff(A) // passes a copy of the bit pattern(just like you zerox a piece of paper and original document
// you keep it and then xerox you give it to your friend) and also A retains the bitpattern for it self.
void doStuff(Cat B) { // B receives a copy of the bitpattern.
B = new Cat(); // B is assigned a new bitpattern i.e overrides the old bitpattern. A had sent just the copy so the original
// bitpattern is there with A.(here your friend scribbles on his xerox paper won't affect your paper.)
}
Okay, I think I'm getting it now from the above code:
The first Cat's bitpattern (A) is transmitted to the method but then is overwritten by the creation of Cat B. The original A Cat still retains the original bitpattern. The second A is now a new Cat and has a new bitpattern, without any changes to the first A Cat. Am I getting it now?
I haven't read the other posts yet but will tonight and see if what I think is correct is supported by those explanations, which I think it is.
Campbell, I think I've got it now after reading your stack explanation. That worked. I think I was getting hung up on the reference name as opposed to the bit pattern and the actual object. But I think I have got it straight now. And I have read all your other explanations and found I consistently understood what you have been saying. So, a great big THANK YOU! to you and everyone who tried to help me. I so appreciate all the effort.
I think I really have it this time! It's a powerful feeling, after feeling so dumb.