The use of the new keyword ensures that objects are constructed and have an address. All 4 of those object, a1,a2,b1,b2 constructed in the main(..) method are local to that method.
12. a1.b1 = b1;
That sets a1's static beta field to a real address. Later in main(..) when you set b1=null it null's out the address of that local Beta object but does not change the address that a1.b1 has already been set to.
15. a1 = null; b1 = null; b2 = null;
Deletes the a1 object and, of course, it's a1.b1. The a2 object is still there and it's static field a2.b2 still has it's value. Thus at line 16 there is only the a2 object with it's static field a2.b2 that still has a valid address, ie, reference.
>> Hmm, I decided to review the definition of 'eligible for garbage collection':
An object is eligible for garbage collection when there are no more
references to that object. References that are held in a variable are
usually dropped when the variable goes out of scope. Or, you can
explicitly drop an object reference by setting the variable to the
special value null. Remember that a program can have multiple
references to the same object; all references to an object must be
dropped before the object is eligible for garbage collection.
So, I've decided that my answer is not as helpful as I thought it would be. Rather than delete it I'm leaving it because it might be helpful, don't pay for it though..
Content will be erased after question is completed.