class B { ... } class A { static B b1; public B b2; } public class Tester { public static void main(String[] args) { B b1 = new B(); B b2 = new B(); A a1 = new A(); A a2 = new A(); a1.b1 = b1; //Siccome b1 è statica, tutte le istanze di tipo dinamico A puntano allo stesso oggetto a1.b2 = b1; //In poche parole, implicitamente c'è scritto anche a2.b1 = b1 a2.b2 = b2; a1 = null; b1 = null; //l'oggetto B() appena dereferenziato rimane referenziato dalla variabile d'istanza statica a2.b1 b2 = null; (1) // altro codice } }
Nello heap vengono creati 2 oggetti di tipo B e 2 oggetti di tipo A. L'oggetto referenziato da b1 viene referenziato dalla variabile d'istanza statica b1, quindi a1.b1 == a2.b1 == B() (di b1). L'oggetto referenziato da b2 viene referenziato anche da a1.b2, non è statico però. Esso viene poi referenziato anche da a2.b2. Facendo a1 = null;, si perde il riferimento all'oggetto A referenziato da esso, e con lui anche il riferimento di a1.b2. Quest'oggetto non è più riferito da nessuno. Facendo b1 = null; si perde l'oggetto B referenziato da b1, che però rimane ancora referenziato da a2.b1. Facendo b2=null; si perde l'oggetto B referenziato da b2, che però rimane referenziato ancora da a2.b2. Dunque l'unico oggetto ad aver perso ogni riferimento è quello inizialmente referenziato da a1, che è infatti anche l'unico a diventare garbage al termine delle istruzioni nel punto (1).