What is the result?
B. hi hi
C. hi hi hi
D. Compilation fails
E. hi, followed by an exception
F. hi hi, followed by an exception
F is correct. The m2 object’s m1 instance variable is never initialized, so when m5 tries to
use it a NullPointerException is thrown.
The answer given explains why the output is as it is. m2 is created as a new Mixer, and its instance variable m2.m1 is never initialised. Therefore it's null. So m5 is set to null. So m5.go() throws a NullPointerException. Is there a particular part of that you're having trouble with?
The class Mixer has a member variable m1, that also can point to a Mixer object (so a Mixer 'has-a' Mixer). So whenever we have a Mixer m, we can refer to m.m1.
However, there are two ways of creating a Mixer. One constructor takes a Mixer as an argument, and initialises m1 to that value. That's what's happening on line 8 (I've just sorted out the code tags for you to make it easier to read). The other constructor takes no arguments, and if we use that m1 is initialised to null. That's what happens on line 7.
So, after line 7, m2 points to a Mixer object, but m2.m1 is null.
After line 8, m3 points to a Mixer object, but m3.m1 references the same object as m2.
On line 10, we set m4 to the value of m3.m1, which is (see line above) the same object as m2. Calling m4.go() is the same as calling m2.go().
On line 12, we set m5 to the value of m2.m1. Which (see above again) is null. So after line 12, m5 is null. Which is why we get an exception on line 13.