0

Edit: I am aware that there are plenty of questions abut pass-by-reference/value and so on, and I've checked a ton of them. I still don't 'get' it. If someone could just explain THIS piece of code like I'm three years old, I think it would finally click.

Edit 2: I'm an idiot. There WAS a main method, I just read over it somehow. Adjusted the example code.

Original post:

I would never play 'reference hide-and-seek' in real life, but I am stumped by the following exam question. I know the answer, but I cannot figure out WHY it is the answer, if that makes any sense. If someone can help me make this 'click', I would greatly appreciate it.

Here is the code:

class Person {
    public String name;
    public int height;
}

class EJavaGuruPassObjects1 {
    public static void main(String args[]) {
        Person p = new Person();
        p.name = "EJava";

        anotherMethod(p);
        System.out.println(p.name);

        someMethod(p);
        System.out.println(p.name);
    }

    static void anotherMethod(Person p) {
        p = new Person();
        p.name = "anotherMethod";
        System.out.println(p.name);
    }

    static void someMethod(Person p) {
        p.name = "someMethod";
        System.out.println(p.name);
    }
}

According to the book I'm using, the code should output:

anotherMethod
EJava
someMethod
someMethod

I can't, for the life of me, figure out why it does this?

The third and fourth line of the answer, someMethod has set the name of 'p' to "someMethod" and then it printed p.name. Okay, no problem there. But anotherMethod does something curious: it seems to assign either a new Person object to 'p', or create a new reference variable that is also called 'p' and assigns the new Person object to that one. I suspect it does the latter.

Now it gets interesting: the method has worked its magic and the remaining code wants to print p.name now. If the existing variable was reassigned (I don't think so, but... maybe?), it should print "anotherMethod" again. If a second 'p' variable was indeed created, we have a problem. Why does it print EJava? How does it know which 'p' reference is adressed?

Pshemo
  • 122,468
  • 25
  • 185
  • 269
Thalia01
  • 11
  • 1
  • 1
    This code wont event compile. you are directly invoking statments in `EJavaGuruPassObjects1` and are declaring the methods you are trying to invoke outside of anything. – SomeJavaGuy Jun 07 '16 at 09:47
  • 2
    This code doesn't even compile, let alone print anything. And when you fix that it still won't execute due to the lack of a `static void main(String[] args)` method. And I don't see 'two Java reference variables with the same name' anywhere. – user207421 Jun 07 '16 at 09:47
  • 1
    If you're aware that the code won't compile, what exactly is this question about? It can't be about 'why it does this', because 'it' doesn't do anything. – user207421 Jun 07 '16 at 09:56
  • @EJP Thing is, the author of the book I'm using is a lot more experienced at Java than I am. What are the odds of me catching a mistake of them? I cannot imagine I'm right here; I feel there is something blatatantly obvious I'm missing. – Thalia01 Jun 07 '16 at 10:00
  • 1
    If you have quoted the code accurately and completely, the book is wrong, and two separate people have told you so. It seems more likely to me that you've omitted either some code or some context. You should also provide a proper citation to the book, publisher, year, edition, author, chapter, section, and page, so it can be checked. StackOverflow isn't meant to be a validation site for arbitrary or misquoted garbage. – user207421 Jun 07 '16 at 10:02
  • @EJP You're absolutely right, I fixed the code. I cannot believe I missed that. I checked it five times and somehow kept reading over it. Thank you for pointing it out. – Thalia01 Jun 07 '16 at 10:10
  • You need to understand that parameters of each method are actually local variables of that method which can be assigned at the moment when we are calling that method. So `p` in `anotherMethod(Person p)` is *local variable* of `someMethod` and its value is assigned at the moment we are calling it like `someMethod(somePerson)` where `p` will copy reference which `somePerson` variable also holds. In your case `somePerson` is also called `p` and it was created in `main` method but that is not a problem because scope of these variables is limited to methods in which they ware *declared*. – Pshemo Jun 07 '16 at 10:29
  • So `p` variable declared in `main` can't be seen by other methods like `anotherMethod` (which has its own `p` local variable - parameter). So it is safe for each method to name their local variables the same, because they know that each of them can have access to only its own local variable. SO even if one method will change value of its own local variable (`p=...`) it will not change value of other variable with same name in other method. That is why `p=new Person(); p.name = "anotherMethod";` affects only `p` which belongs to `anotherMethod` but doesn't affect `p` of `main` method. – Pshemo Jun 07 '16 at 10:34
  • What may confuse you now is "then why `someMethod` which skips `p = new Person();` is able to affect `p` from `main`?". Answer is: because `someMethod` didn't change value of its own `p` it holds reference to same Person object as `p` in main (since we invoked it in main via `someMethod(p)` which let `p` of `someMethod` to copy value (reference) of `p` in `main` method). So when we are using `p.name` in `someMethod` we are accessing `name` variable of same object so any modification to that variable will also be seen by both `p` variables. – Pshemo Jun 07 '16 at 10:52
  • @Pshemo I can't thank you enough. I've been staring at the problem for DAYS, googling it, cursing in several languages, and your explanation FINALLY completed the puzzle. I now know where I went wrong: I completely forgot that, if you create an object, it doesn't keep existing forever! I was so focussed on figuring out which objects are in scope, that I somehow didn't realize objects can go OUT of scope as well. No wonder I got stuck! Thank you! – Thalia01 Jun 07 '16 at 11:30
  • Good for you :) Now try to remember that scope affects only *variables*. *Values/objects* can be shared among many variables even in different scopes and precisely to make this possible we have methods/constructors. – Pshemo Jun 07 '16 at 11:35

0 Answers0