When we create an object in Java, an object is strong by default. To create a Phantom Reference Object, we must explicitly specify this to the JVM. Phantom Reference Objects are created as phantom reference object is eligible for garbage collection, but it is not collected instantly. Instead, it is pushed into a ReferenceQueue so that all such enqueued references can be cleared.
Constructors of this class is shown in the table below
| Constructor Parameters | Constructor Description |
|---|---|
| PhantomReference (T,ReferenceQueue <T> q) : | Creates a new phantom reference that refers to the given object and is registered with the given queue. It is possible to create a phantom reference with a null queue, but such a reference is completely useless: Its get method will always return null and, since it does not have a queue, it will never be enqueued. |
Methods inherited from Reference Class are as follows:
| Method Name | Method Description |
|---|---|
| get() | Returns this reference object’s referent. Because the referent of a phantom reference is always inaccessible, this method always returns null. |
| clear() | Clears this reference object. Invoking this method will not cause this object to be enqueued. |
| enque() | Adds this reference object to the queue with which it is registered, if any. |
| isEnqueued() | Tells whether this reference object has been enqueued, either by the program or by the garbage collector. |
Example 1:
Java
// Java Program to illustrate PhantomReference class// of java.lang.ref packageÂ
// Importing PhantomReference and ReferenceQueue classes// from java.lanf.ref packageimport java.lang.ref.PhantomReference;import java.lang.ref.ReferenceQueue;Â
// Class 1// Helper classclass HelperClass {Â
    // Method inside HelperClass    void Display()    {        // Print statement whenever the function is called        System.out.println("Display Function invoked ...");    }}Â
// Class 2// Main classpublic class GFG {    // MyClass    // Main driver method    public static void main(String[] args)    {        // Creating a strong object of HelperClass        HelperClass obj = new HelperClass();Â
        // Creating a reference queue of HelperClass type        ReferenceQueue<HelperClass> rq            = new ReferenceQueue<>();Â
        // Creating a phantom reference object using rq        PhantomReference<HelperClass> pobj            = new PhantomReference<>(obj, rq);Â
        // Display message only        System.out.println(            "-> Calling Display Function using strong object:");Â
        // Calling the display method over the object of        // HelperClass        obj.Display();Â
        // Display message for better readability        System.out.println("-> Object set to null");Â
        obj = null;Â
        // Getting elements in PhantomReference object        // using standard get() method        obj = pobj.get();Â
        // Display status of objects after fetching        // PhantomReference class objects        System.out.println(            "-> Object status after fetching from PhantomReference now : "            + obj);Â
        // Display message only        System.out.println(            "-> Calling Display Function after retrieving from weak Object");Â
        // Try block to check for exceptions        try {            obj.Display();        }Â
        // Catch block to handle the exceptions        catch (Exception E) {Â
            // Print message when an exception occurred            System.out.println("-> Error : " + E);        }    }} |
-> Calling Display Function using strong object: Display Function invoked ... -> Object set to null -> Object status after fetching from PhantomReference now : null -> Calling Display Function after retrieving from weak Object -> Error : java.lang.NullPointerException
Hence, it is seen that unlike Soft and Weak References, Phantom Reference always returns null.
Example 2:
Java
// Java Program to illustrate PhantomReference class// of java.lang.ref packageÂ
// Importing Phantomreference and RefereenceQueue classes// from java.lang.ref packageimport java.lang.ref.PhantomReference;import java.lang.ref.ReferenceQueue;Â
// Class 1// HelperClassclass X {Â
    // Method    // To print simply    void show()    {Â
        // Display message whenever        // show() method is called        System.out.println("show () from X invoked..");    }}Â
// Class 2// Main classpublic class GFG {Â
    // Main driver method    public static void main(String[] args)    {Â
        // Creating default object of X class        X obj = new X();Â
        // Creating new reference queue object        ReferenceQueue<X> rq = new ReferenceQueue<X>();Â
        // Creating an object of PhantomReference class        // of X class type with RefereneQueue object        // reference queue        PhantomReference<X> phantomobj            = new PhantomReference<X>(obj, rq);Â
        // Display message        System.out.println(            "-> Trying to retrieve object from Phantom Reference :");Â
        // Try block to check for exceptions        try {Â
            // this will always throw error as it has been            // collected            // by the garbage collector            phantomobj.get().show();        }Â
        // Catch block to handle the exceptions        catch (Exception e) {Â
            // Print and display the exception            System.out.println(e);        }    }} |
-> Trying to retrieve object from Phantom Reference : java.lang.NullPointerException

