"Hej, Amigo!"

"Hej, Rishi!"

"Nå, hvordan var din dag?"

"Strålende! I dag fortalte Bilaabo mig om rekursion, og Ellie fortalte mig om svage og bløde referencer."

"Fortalte hun dig om fantomreferencer?"

"Snakker du om PhantomReference? Hun nævnte det, men forklarede det ikke i detaljer."

"Godt, så håber jeg ikke, at du har noget imod, hvis jeg udfylder dette hul."

"Selvfølgelig! Jeg vil lytte til dig med glæde, Rishi!"

"Fantastisk. Så begynder jeg."

"Fantomreferencer er de svageste referencer af alle. De har kun effekt, hvis et objekt slet ikke har nogen referencer udover fantomreferencer."

PhantomReference - 1

"En PhantomReference bruges i en kompleks objektsletningsprocedure.  Dette kan være nødvendigt, når et objekt gør noget uden for Java-maskinen, f.eks. kalder det lavniveau OS-funktioner eller skriver sin tilstand til en fil eller gør noget andet meget vigtigt."

"Her er et eksempel på, hvordan du kan bruge det:"

Eksempel på oprettelse af fantomreferencer
// 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));
}

"Jeg vil gerne henlede opmærksomheden på den sidste linje igen. Ikke alene sendes objekt x til PhantomReference - en særlig kø af fantomreferencer er det også."

"Hvorfor har vi brug for denne kø?"

"Det er det, jeg vil fortælle dig nu."

"Når du ødelægger et objekt, der holdes af en fantomreference, bliver det ødelagt, men det slettes ikke fra hukommelsen! Hvad synes du om det?!"

"Så hvordan virker det?"

"Der er en del nuancer her, så jeg starter med det enkleste."

"Hvis kun fantomreferencer til et objekt er tilbage, så er dette, hvad der vil ske med det:"

" Trin 1. Under den næste skraldopsamling vil finalize()-metoden blive kaldt på objektet. Men hvis finalize()-metoden ikke er blevet tilsidesat, springes dette trin over, og trin 2 udføres med det samme."

" Trin 2. Under den næste skraldopsamling placeres objektet i en speciel kø af fantomobjekter. Det vil blive slettet fra denne kø, når clear()-metoden kaldes på PhantomReference."

"Hvem kalder det? Objektet blev slettet, ikke?"

"Nå, objektet døde faktisk i vores verden (Java-verdenen), men det er ikke forsvundet. Det forbliver som et fantom - køen af ​​fantomobjekter har stadig en reference til det. Den samme referencekø, hvis reference vi omhyggeligt videregivet til PhantomReference -konstruktøren."

"Så denne ReferenceQueue er ligesom efterlivet?"

"Mere som en fantomverden."

"Og et fantomobjekt kan kun slettes ved at kalde clear() på dets fantomreference."

"Sådan fortsætter du det forrige eksempel:"

Eksempel på oprettelse af fantomreferencer
// 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();
}

"Jeg forstår, at der sker noget her. Jeg forstår næsten endda præcis, hvad der sker."

"Men hvordan bruger du det i praksis?"

"Her er et bedre eksempel:"

Eksempel på oprettelse af fantomreferencer
// 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));
}
Denne tråd vil overvåge fantomkøen og fjerne objekter fra den
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();
Dette er en klasse, der arver PhantomReference og har en close() metode
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!");
 }
}

"Vi gjorde tre ting her."

"Først oprettede vi PhantomInteger- klassen, som arver PhantomReference < Integer >."

"For det andet har denne klasse en speciel close ()-metode. Behovet for at kalde denne metode er det, der fik alt dette i gang.

"For det tredje erklærede vi en speciel tråd: referenceThread . Den venter i en løkke, indtil et andet objekt dukker op i fantomkøen. Så snart dette sker, fjerner tråden objektet fra fantomkøen og kalder sin close () metode. Og så clear()-metoden. Og det er det. Fantomet kan gå videre til en bedre verden. Det vil ikke længere bekymre os i vores."

"Så interessant, men det hele lykkedes."

"Vi sporer faktisk en kø af døende genstande, og så kan vi kalde en speciel metode for hver af dem."

"Men husk, du kan ikke kalde metoden på selve objektet.  Du kan ikke få en reference til det! PhantomReferences get()-metode returnerer altid null. "

"Men vi arver PhantomReference!"

"Selv inden for en underklasse af PhantomReference returnerer get() metoden null."

"Så jeg gemmer bare en reference til objektet i konstruktøren"

"Ah. Men sådan en reference ville være en StrongReference, og objektet vil aldrig ende i fantomkøen!"

"Dang. Okay, giv op. Hvis det er umuligt, så er det umuligt."

"Okay, godt. Jeg håber, du har lært noget værdifuldt af dagens lektion."

"Ja, der var så meget nyt materiale. Og jeg troede, jeg allerede vidste alt. Tak for lektionen, Rishi."

"Du er velkommen. Det er det, slap af. Men glem det ikke - vi har endnu en lektion i aften."