The output is 300-300-100-100-100.
In the main method, a new instance of the Foo class is created with x = 300. The getX() method is called on this instance, returning 300, which is printed.
Then, the fooBar() method is called with the foo instance as an argument. Inside fooBar(), a new instance of Foo is created with x = 100, and this new instance is returned.
Back in the main method, the getX() method is called on the original foo instance, which still has x = 300, returning 300, which is printed.
Then, the getX() method is called on the fooFoo instance, which was assigned the returned value from fooBar(). Since fooFoo is now referencing the new Foo instance with x = 100, 100 is returned and printed.
Finally, the foo instance is assigned the returned value from calling fooBar() with fooFoo as an argument. This means foo is now referencing the new Foo instance with x = 100. The getX() method is called on foo, returning 100, which is printed.
The getX() method is called on fooFoo again, returning 100, which is printed.