class Mixer {
    Mixer() {}
    Mixer(Mixer m) { m1 = m; }
    Mixer m1;

    public static void main(String args[]) {
        Mixer m2 = new Mixer();
        Mixer m3 = new Mixer(m2);  m3.go();
        Mixer m4 = m3.m1;          m4.go();
        Mixer m5 = m2.m1;          m5.go();
        void go() { System.out.println("hi"); }

The answer to is " hi hi followed by an exception"

Here are my doubts:

a) When m2 is passed as an arg to Mixer constructor, are we passing the address to the Mixer() object m2 points to? If so, m1 = m will give the same address to m1 and hence m1 and m2 will point to same object?

b) How do you interpret m3.m1 and m2.m1? I mean to say, what is happening? I've seen RefVar.MethodInvocation as the syntax. First time coming across RefVar.RefVar. What exactly is happening? Object is created? Adresses are copied? I'm thoroughly confused :(

c) Finally how's the output coming the way it is?

Help please. Thanks, sincerely.

a) In Java we usually speak of "object references", not "memory addresses". Memory addresses are a low-level concept that isn't really visible to Java programmers. But yes, when you pass m2 to the Mixer constructor, you're passing a reference to the object that m2 refers to. So the m1 variable of the newly creater Mixer object will refer to the same object as the variable m2.

b) m1 is an instance variable of the Mixer class. So each Mixer object has its own variable called m1. Writing someMixerObject.m1 will access the variable m1 that belongs to that Mixer object.

c) If a Mixer object is created using the default constructor, its m1 variable will be null (because the default constructor does not set m1). If it is created using the one-argument constructor its m1 variable will be the argument passed to that constructor.

So when you create m2 in your main method, its m1 variable is null because you used the default constructor. m3's m1 variables is equal to m2 because you used the 1-argument constructor with m2 as the argument. So when you do m4 = m3.m1, m4 will be equal to m2. And when you do m5 = m2.m1, m5 will be equal to null because, as already said, m2's m1 variable is null.

Since you're not allowed to call methods on null, you get an exception when you invoke

Very clear and comprehensive reply
This question has already been answered. Start a new discussion instead.