0

This example is taken from the Java programming book; 4th Edition.

After stumbling upon this code example I am mystified at why it still prints out the new reference to the object, even though we declared it to be 'null'. In theory, we're altering the references to the object which is shared between the whole program, though we initialize the object to null in the commonName method. At the point of the flow of control at commonName, the field in the body constructor is initialized to "Sirius"; when we alter the references to the object (In Java you call-by-value) the field is changed to Dog Star. The last line of the method we set the whole object to null, once we print out the object the runtime should greet us with a null references.

The only way to get round this is by setting the commonName method as final. Can any Java guru explain why this happens, especially in any call-by-value language.

class PassRef
{
    public static void main (String[] args) {
        Body sirius = new Body ("Sirus", null);
        System.out.println ("before: " + sirius);
        commonName(sirius);
        System.out.println("after: " + sirius);
    }

    public static void commonName (Body bodyref) {
        bodyref.name = "Dog Star";
        bodyref = null;
    }
}

The output:

before: 0 (Sirius)
after:  0 (Dog Star)
  • You are not passing a reference here when you call `commonName(sirius`) a copy of object `sirius` is created and than passed to the method. The copy and the original object now both refer to the same thing. – RanRag Oct 06 '12 at 15:58
  • @Serge: I believe so because java is always pass by value and when you pass an object reference it's copy is made and than passed. – RanRag Oct 06 '12 at 16:01
  • 2
    @RanRag: This is nonsense. Java does not automatically copy the object this way. – Don Roby Oct 06 '12 at 16:07
  • 1
    @RanRag it makes a copy of reference, not the copy of object. – Serge Oct 06 '12 at 16:11
  • @RanRag my question was about yours `a copy of object sirius is created and than passed to the method.` – Serge Oct 06 '12 at 16:12
  • 2
    @Serge: I think he misspelled because in his second explanation he wrote `object reference it's copy is made `. – RanRag Oct 06 '12 at 16:15
  • @Noob his first comment had to be clarified. now everything is fine :) – Serge Oct 06 '12 at 16:17

1 Answers1

5

You're mystified only because you don't understand what pass by value means.

The common method cannot alter the reference that it's passed. That's why null is ignored and you print the new value.

You can alter the state of the object that the passed reference points to, but you cannot change the value of the reference itself.

duffymo
  • 305,152
  • 44
  • 369
  • 561
  • @LewisRobbins why it can't? The language specification allow this. it's a local variable, so a method may do whatever it likes. – Serge Oct 06 '12 at 15:59
  • Compiler warning? Why? No, this is the way the language works. The reference is giving you this example so you can understand how things will work when you're writing Java on your own. – duffymo Oct 06 '12 at 15:59
  • It's not a local variable; it's declared elsewhere and passed to the method. – duffymo Oct 06 '12 at 15:59
  • 1
    bodyRef is a formal parameter of a member function. it is a local variable! – Serge Oct 06 '12 at 16:01
  • @duffymo okay that explains it. Am I correct in thinking that sirius and bodyref still refer to the same underlying object? – Lewis Robbins Oct 06 '12 at 16:02
  • 1
    I call variables that are declared within method scope local variables. You and I have a different idea about what that term means. – duffymo Oct 06 '12 at 16:02
  • @Lewis - you initialized sirius using new and passed that reference by value to the commonName method. The reference value is the same in both parts of the code; both refer to the Body instance out on the heap that you created with new and initialized with the constructor. – duffymo Oct 06 '12 at 16:04
  • @duffymo - To sum it up: When I change the field bodyref.name the name is change in the underlying object that BOTH the methods share (main & commonName); the null assignment only changes the local variable inside commonName; siruis remains unchanged. All I'm changing is the value, not the state, as bodyRef is a copy of sirius because of pass-by-value. – Lewis Robbins Oct 06 '12 at 16:08
  • @duffymo yes, and bodyref is declared within the method scope. it is unknown outside this method. – Serge Oct 06 '12 at 16:10
  • @duffymo null is not ignore, per se - it adds confusion to the reader who may find your answer. – Lewis Robbins Oct 07 '12 at 08:39
  • @duffymo I know. You state 'null' is ignored; which is correct for the underlying object. When I first read your answer I assumed the JVM/JIT ignored the statement which your answer seems to apply; I'm not arguing with you anymore; the comment section is not meant for this. – Lewis Robbins Oct 07 '12 at 14:14
  • @duffymo I'm not arguing with you; stop with the patronizing threats, then perhaps I could start to discuss Java with you. I never knew using the 'I'm bigger than you' approach still was used. Alas, I said that in the comment before you. I am; hence my question. Can we pleases stop this petty argument? You have also misinterpreted my comments on occasions. – Lewis Robbins Oct 08 '12 at 15:46
  • If you would have read my question - This example is taken from the Java programming book; 4th Edition. I will not expect any further solicitations from you. – Lewis Robbins Oct 08 '12 at 15:58