– Szia Amigo!

– Szia Rishi!

– Nos, milyen napod volt?

"Zseniális! Ma Bilaabo a rekurzióról, Ellie pedig a gyenge és lágy utalásokról mesélt."

– Mesélt önnek a fantomreferenciákról?

– A PhantomReference-ről beszél? Említette, de nem magyarázta el részletesen.

– Remek, akkor remélem, nem bánja, ha kitöltöm ezt a hiányt.

"Természetesen! Örömmel hallgatlak, Rishi!"

– Remek. Akkor kezdem.

"A fantomhivatkozások a leggyengébb hivatkozások az összes közül. Csak akkor érvényesülnek, ha egy objektumnak a fantomhivatkozásokon kívül más hivatkozása sincs."

PhantomReference – 1

"A PhantomReference egy összetett objektumtörlési eljárásban használatos.  Erre akkor lehet szükség, ha egy objektum a Java gépen kívül csinál valamit, pl. alacsony szintű operációs rendszer függvényeket hív meg, állapotát fájlba írja, vagy valami más nagyon fontos dolgot csinál."

"Íme egy példa arra, hogyan használhatja:"

Példa fantomhivatkozások létrehozására
// Special queue for phantom objects
ReferenceQueue<Integer> queue = new ReferenceQueue<Integer>();

// List of phantom references
ArrayList<PhantomReference<Integer>> list = new ArrayList<PhantomReference<Integer>>();

// Create 10 objects and add them to the list using phantom references
for ( int i = 0; i < 10; i++)
{
 Integer x = new Integer(i);
 list.add(new PhantomReference<Integer>(x, queue));
}

"Újra az utolsó sorra szeretném felhívni a figyelmet. Nem csak az x objektum kerül át a PhantomReference- be , hanem egy speciális fantomhivatkozási sor is."

– Miért van szükségünk erre a sorra?

– Most ezt fogom elmondani.

"Ha elpusztítasz egy fantomreferencia által tartott tárgyat, az megsemmisül, de nem törlődik a memóriából! Mit gondolsz erről?!"

– Szóval, ez hogyan működik?

– Van itt jó néhány árnyalat, úgyhogy a legegyszerűbbel kezdem.

"Ha csak fantomhivatkozások maradnak egy objektumra, akkor ez történik vele:

" 1. lépés . A következő szemétgyűjtés során a finalize() metódus meghívásra kerül az objektumon. Ha azonban a finalize() metódus nem lett felülírva, akkor ez a lépés kimarad, és a 2. lépés azonnal végrehajtásra kerül."

" 2. lépés . A következő szemétgyűjtés során az objektum a fantomobjektumok speciális sorába kerül. A PhantomReference-ben a clear() metódus meghívásakor törlődik ebből a sorból."

"Ki hívja? Az objektumot törölték, igaz?"

"Nos, az objektum valóban meghalt a mi világunkban (a Java világban), de nem tűnt el. Fantomként marad – a fantomobjektumok sora még mindig tartalmaz utalást rá. Ugyanaz a ReferenceQueue, amelyre olyan gondosan hivatkozunk átadta a PhantomReference konstruktornak."

– Szóval ez a ReferenceQueue olyan, mint a túlvilág?

– Inkább egy fantomvilág.

"És egy fantomobjektumot csak úgy lehet törölni, ha a fantomreferenciáján a clear()-t meghívjuk."

"Íme, hogyan folytassuk az előző példát:"

Példa fantomhivatkozások létrehozására
// Special queue for phantom objects
ReferenceQueue<Integer> queue = new ReferenceQueue<Integer>();

// List of phantom references
ArrayList<PhantomReference<Integer>> list = new ArrayList<PhantomReference<Integer>>();

// Create 10 objects and add them to the list using phantom references
for ( int i = 0; i < 10; i++)
{
 Integer x = new Integer(i);
 list.add(new PhantomReference<Integer>(x, queue));
}

// Call the garbage collector and hope it will listen to us :)
// It should destroy all phantom reachable objects and put them in the queue
// of phantoms
System.gc();

// Get all objects from the queue
Reference<? extends Integer>referenceFromQueue;
while ((referenceFromQueue = queue.poll()) != null)
{
 // Display the object on the screen
 System.out.println(referenceFromQueue.get());

 // Clear the reference
 referenceFromQueue.clear();
}

"Megértem, hogy itt valami történik. Szinte még azt is pontosan értem, hogy mi történik."

– De hogyan használja ezt a gyakorlatban?

"Íme egy jobb példa:"

Példa fantomhivatkozások létrehozására
// Special queue for phantom objects
ReferenceQueue<Integer> queue = new ReferenceQueue<Integer>();

// List of phantom references
ArrayList<PhantomInteger> list = new ArrayList<PhantomInteger>();

// Create 10 objects and add them to the list using phantom references
for ( int i = 0; i < 10; i++)
{
 Integer x = new Integer(i);
 list.add(new PhantomInteger (x, queue));
}
Ez a szál figyeli a fantomsort, és eltávolítja belőle az objektumokat
Thread referenceThread = new Thread()
{
 public void run()
 {
  while (true)
  {
   try
   {
    // Get the new object from the queue. If there is no object, then we wait!
    PhantomInteger ref = (PhantomInteger)queue.remove();
    // Call the close method on it
    ref.close();
    ref.clear();
   }
   catch (Exception ex)
   {
    // Write errors to a log
   }
  }
 }
};
// Run the thread as a daemon
referenceThread.setDaemon(true);
referenceThread.start();
Ez egy olyan osztály, amely a PhantomReference-t örökli, és van egy close() metódusa
static class PhantomInteger extends PhantomReference<Integer>
{
 PhantomInteger(Integer referent, ReferenceQueue<? super Integer> queue)
 {
  super(referent, queue);
 }

 private void close()
 {
  System.out.println("Bad Integer totally destroyed!");
 }
}

– Három dolgot csináltunk itt.

"Először is létrehoztuk a PhantomInteger osztályt, amely örökli a PhantomReference < Integer > értéket."

"Másodszor, ennek az osztálynak van egy speciális bezárási () metódusa. Ennek a metódusnak az igénye indította el az egészet.

"Harmadszor deklaráltunk egy speciális szálat: referenceThread . Egy ciklusban vár, amíg egy másik objektum megjelenik a fantomsorban. Amint ez megtörténik, a szál eltávolítja az objektumot a fantomsorból, és meghívja a close () metódusát . a clear() módszer. És ennyi. A fantom továbbléphet egy jobb világ felé. A miénkben többé nem fog zavarni minket."

– Annyira érdekes, de minden sikerült.

"Tulajdonképpen egy sor haldokló objektumot követünk nyomon, és akkor mindegyikhez hívhatunk egy speciális metódust."

"De ne feledje, magán az objektumon nem hívhatja meg a metódust.  Nem kaphat hivatkozást rá! A PhantomReference get() metódusa mindig nullát ad vissza. "

– De mi örököljük a PhantomReference-t!

"A get() metódus még a PhantomReference alosztályán belül is nullát ad vissza."

"Tehát csak elmentek egy hivatkozást az objektumra a konstruktorban"

"Ah. De egy ilyen hivatkozás StrongReference lenne, és az objektum soha nem kerül a fantomsorba!"

Oké, add fel. Ha ez lehetetlen, akkor lehetetlen.

"Rendben, jó. Remélem, tanultál valami értékeset a mai leckéből."

"Igen, annyi új anyag volt. És azt hittem, már mindent tudok. Köszönöm a leckét, Rishi."

"Szívesen. Ez az, menj pihenni. De ne felejtsd el, ma este van még egy leckénk."