"Hai, Amigo!"

"Hai, Rishi!"

"Nah, bagaimana harimu?"

"Brilian! Hari ini Bilaabo memberi tahu saya tentang rekursi, dan Ellie memberi tahu saya tentang referensi yang lemah dan lembut."

"Apakah dia memberitahumu tentang referensi hantu?"

"Apakah kamu berbicara tentang PhantomReference? Dia menyebutkannya, tetapi tidak menjelaskannya secara detail."

"Bagus, kalau begitu aku harap kamu tidak keberatan jika aku mengisi celah ini."

"Tentu saja! Aku akan mendengarkanmu dengan senang hati, Rishi!"

"Bagus. Kalau begitu aku akan mulai."

"Referensi phantom adalah referensi terlemah dari semuanya. Mereka memiliki efek hanya jika objek tidak memiliki referensi sama sekali selain referensi phantom."

Referensi Hantu - 1

"PhantomReference digunakan dalam prosedur penghapusan objek yang kompleks.  Ini mungkin diperlukan saat objek melakukan sesuatu di luar mesin Java, misalnya, memanggil fungsi OS tingkat rendah atau menulis statusnya ke file atau melakukan hal lain yang sangat penting."

"Inilah contoh bagaimana Anda dapat menggunakannya:"

Contoh membuat referensi hantu
// 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));
}

"Saya ingin menarik perhatian ke baris terakhir lagi. Tidak hanya objek x yang diteruskan ke PhantomReference antrean khusus referensi phantom juga demikian."

"Mengapa kita membutuhkan antrean ini?"

"Itulah yang akan kuberitahukan padamu sekarang."

"Ketika kamu menghancurkan objek yang dipegang oleh referensi hantu, itu akan hancur, tetapi tidak dihapus dari memori! Bagaimana menurutmu tentang itu?!"

"Jadi, bagaimana cara kerjanya?"

"Ada beberapa nuansa di sini, jadi saya akan mulai dengan yang paling sederhana."

"Jika hanya referensi hantu ke suatu objek yang tersisa, maka inilah yang akan terjadi padanya:"

" Langkah 1 . Selama pengumpulan sampah berikutnya, metode finalize() akan dipanggil pada objek. Namun, jika metode finalize() belum ditimpa, maka langkah ini dilewati, dan langkah 2 segera dijalankan."

" Langkah 2 . Selama pengumpulan sampah berikutnya, objek ditempatkan dalam antrean khusus objek hantu. Objek tersebut akan dihapus dari antrean ini saat metode clear() dipanggil pada PhantomReference."

"Siapa yang menyebutnya? Benda itu dihapus, kan?"

"Yah, objek itu memang mati di dunia kita (dunia Jawa), tapi itu belum menghilang. Itu tetap sebagai hantu — antrean objek hantu masih menyimpan referensi untuk itu. ReferensiQueue yang sama yang referensinya kita sangat hati - hati diteruskan ke konstruktor PhantomReference ."

"Jadi ReferenceQueue ini seperti akhirat?"

"Lebih seperti dunia hantu."

"Dan objek phantom hanya dapat dihapus dengan memanggil clear() pada referensi phantomnya."

"Begini cara melanjutkan contoh sebelumnya:"

Contoh membuat referensi hantu
// 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();
}

"Saya mengerti bahwa sesuatu sedang terjadi di sini. Saya bahkan hampir mengerti persis apa yang sedang terjadi."

"Tapi bagaimana Anda menggunakan ini dalam praktik?"

"Ini contoh yang lebih baik:"

Contoh membuat referensi hantu
// 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));
}
Utas ini akan memantau antrean hantu dan menghapus objek darinya
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();
Ini adalah kelas yang mewarisi PhantomReference dan memiliki metode close()
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!");
 }
}

"Kami melakukan tiga hal di sini."

"Pertama, kami membuat kelas PhantomInteger , yang mewarisi PhantomReference < Integer >."

"Kedua, kelas ini memiliki metode close () khusus. Kebutuhan untuk memanggil metode ini adalah yang memulai semua ini.

"Ketiga, kami mendeklarasikan utas khusus: referenceThread . Ia menunggu dalam satu lingkaran hingga objek lain muncul dalam antrean hantu. Segera setelah ini terjadi, utas menghapus objek dari antrean hantu dan memanggil metode tutup (). Dan kemudian metode clear(). Dan begitulah. Hantu itu bisa pindah ke dunia yang lebih baik. Itu tidak akan lagi mengganggu kita di dunia kita."

"Sangat menarik, tapi semuanya berhasil."

"Kami benar-benar melacak antrean objek yang sekarat, lalu kami dapat memanggil metode khusus untuk masing-masing objek tersebut."

"Tapi ingat, Anda tidak bisa memanggil metode pada objek itu sendiri.  Anda tidak bisa mendapatkan referensi untuk itu! Metode get() The PhantomReference selalu mengembalikan nol. "

"Tapi kami mewarisi PhantomReference!"

"Bahkan di dalam subkelas PhantomReference, metode get() mengembalikan null."

"Jadi saya hanya menyimpan referensi ke objek di konstruktor"

"Ah. Tapi referensi seperti itu akan menjadi StrongReference, dan objek tersebut tidak akan pernah berakhir di antrean hantu!"

"Dang. Oke, menyerahlah. Jika tidak mungkin, maka tidak mungkin."

"Oke, bagus. Saya harap Anda telah mempelajari sesuatu yang berharga dari pelajaran hari ini."

“Ya, banyak sekali materi baru. Dan saya pikir saya sudah tahu semuanya. Terima kasih atas pelajarannya, Rishi.”

"Sama-sama. Itu saja, santai saja. Tapi jangan lupa—kita ada pelajaran lagi malam ini."