How to Check If an Object Implements an Interface in Java

JavaJavaBeginner
Practice Now

Introduction

In this lab, you will learn how to check if an object implements a specific interface in Java. We will explore the use of the instanceof keyword, a fundamental tool for runtime type checking.

Through hands-on exercises, you will apply instanceof to verify interface implementation, test scenarios involving multiple interfaces, and handle cases with null or non-implementing objects. This lab will provide you with practical skills for determining the actual type of an object and leveraging interface-specific functionalities.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL java(("Java")) -.-> java/BasicSyntaxGroup(["Basic Syntax"]) java(("Java")) -.-> java/ObjectOrientedandAdvancedConceptsGroup(["Object-Oriented and Advanced Concepts"]) java(("Java")) -.-> java/SystemandDataProcessingGroup(["System and Data Processing"]) java/BasicSyntaxGroup -.-> java/if_else("If...Else") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/classes_objects("Classes/Objects") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/oop("OOP") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/interface("Interface") java/SystemandDataProcessingGroup -.-> java/object_methods("Object Methods") subgraph Lab Skills java/if_else -.-> lab-560009{{"How to Check If an Object Implements an Interface in Java"}} java/classes_objects -.-> lab-560009{{"How to Check If an Object Implements an Interface in Java"}} java/oop -.-> lab-560009{{"How to Check If an Object Implements an Interface in Java"}} java/interface -.-> lab-560009{{"How to Check If an Object Implements an Interface in Java"}} java/object_methods -.-> lab-560009{{"How to Check If an Object Implements an Interface in Java"}} end

Apply instanceof for Interface Check

In this step, we will explore how to use the instanceof keyword in Java to check if an object is an instance of a specific interface. This is a common task when you have a variable of a superclass or interface type and you need to determine the actual type of the object it refers to, especially if you want to call methods specific to a particular interface.

First, let's define a simple interface and a class that implements it.

  1. Open the WebIDE editor.

  2. In the File Explorer on the left, make sure you are in the ~/project directory.

  3. Create a new file named Printable.java. You can do this by right-clicking in the File Explorer and selecting "New File", then typing Printable.java.

  4. Open Printable.java and add the following code:

    package project;
    
    public interface Printable {
        void print();
    }

    This defines a simple interface named Printable with one method, print().

  5. Save the file (Ctrl+S or Cmd+S).

Now, let's create a class that implements the Printable interface.

  1. In the ~/project directory, create a new file named Document.java.

  2. Open Document.java and add the following code:

    package project;
    
    public class Document implements Printable {
        private String content;
    
        public Document(String content) {
            this.content = content;
        }
    
        @Override
        public void print() {
            System.out.println("Printing Document: " + content);
        }
    }

    This class Document implements the Printable interface and provides an implementation for the print() method.

  3. Save the file.

Finally, let's create a main class to demonstrate the use of instanceof with the interface.

  1. In the ~/project directory, create a new file named InterfaceCheck.java.

  2. Open InterfaceCheck.java and add the following code:

    package project;
    
    public class InterfaceCheck {
        public static void main(String[] args) {
            Object obj1 = new Document("Important Report");
            Object obj2 = "Just a String";
    
            // Check if obj1 is an instance of Printable
            if (obj1 instanceof Printable) {
                System.out.println("obj1 implements Printable");
                Printable p1 = (Printable) obj1; // Cast to Printable
                p1.print(); // Call the print method
            } else {
                System.out.println("obj1 does not implement Printable");
            }
    
            System.out.println("---");
    
            // Check if obj2 is an instance of Printable
            if (obj2 instanceof Printable) {
                System.out.println("obj2 implements Printable");
                Printable p2 = (Printable) obj2; // This line would cause a ClassCastException if executed
                p2.print();
            } else {
                System.out.println("obj2 does not implement Printable");
            }
        }
    }

    In this code:

    • We create two Object variables, obj1 which refers to a Document object (which implements Printable), and obj2 which refers to a String object (which does not implement Printable).
    • We use if (obj1 instanceof Printable) to check if the object referenced by obj1 is an instance of the Printable interface.
    • If it is, we print a message and then cast obj1 to the Printable type using (Printable) obj1. Casting allows us to treat the Object as a Printable and call its print() method.
    • We do the same check for obj2. Since String does not implement Printable, the else block will be executed.
  3. Save the file.

Now, let's compile and run the code.

  1. Open the Terminal at the bottom of the WebIDE. Ensure you are in the ~/project directory.

  2. Compile the Java files:

    javac Printable.java Document.java InterfaceCheck.java

    If there are no errors, this command will create Printable.class, Document.class, and InterfaceCheck.class files.

  3. Run the InterfaceCheck program:

    java InterfaceCheck

    You should see output similar to this:

    obj1 implements Printable
    Printing Document: Important Report
    ---
    obj2 does not implement Printable

This output confirms that instanceof correctly identified that obj1 implements Printable while obj2 does not. Using instanceof before casting is crucial to prevent ClassCastException errors at runtime.

Test with Multiple Interfaces

In this step, we will extend our understanding of instanceof by working with multiple interfaces. A single class in Java can implement multiple interfaces, and instanceof can be used to check for each of them.

First, let's define another interface.

  1. Open the WebIDE editor.

  2. In the ~/project directory, create a new file named Editable.java.

  3. Open Editable.java and add the following code:

    package project;
    
    public interface Editable {
        void edit(String newContent);
    }

    This defines an interface named Editable with one method, edit().

  4. Save the file.

Now, let's modify our Document class to implement both Printable and Editable.

  1. Open the Document.java file in the ~/project directory.

  2. Modify the class declaration to implement both interfaces:

    package project;
    
    public class Document implements Printable, Editable {
        private String content;
    
        public Document(String content) {
            this.content = content;
        }
    
        @Override
        public void print() {
            System.out.println("Printing Document: " + content);
        }
    
        @Override
        public void edit(String newContent) {
            this.content = newContent;
            System.out.println("Document edited.");
        }
    }

    We've added , Editable to the class declaration and provided an implementation for the edit() method.

  3. Save the file.

Next, let's modify our main class InterfaceCheck.java to test for both interfaces.

  1. Open the InterfaceCheck.java file in the ~/project directory.

  2. Replace the existing code with the following:

    package project;
    
    public class InterfaceCheck {
        public static void main(String[] args) {
            Object obj1 = new Document("Initial Content");
            Object obj2 = "Just a String";
    
            System.out.println("Checking obj1:");
            // Check if obj1 is an instance of Printable
            if (obj1 instanceof Printable) {
                System.out.println("obj1 implements Printable");
                Printable p1 = (Printable) obj1;
                p1.print();
            } else {
                System.out.println("obj1 does not implement Printable");
            }
    
            // Check if obj1 is an instance of Editable
            if (obj1 instanceof Editable) {
                System.out.println("obj1 implements Editable");
                Editable e1 = (Editable) obj1; // Cast to Editable
                e1.edit("Modified Content"); // Call the edit method
                // After editing, let's print again to see the change
                if (obj1 instanceof Printable) { // We know it is, but demonstrating
                    Printable p1_after_edit = (Printable) obj1;
                    p1_after_edit.print();
                }
            } else {
                System.out.println("obj1 does not implement Editable");
            }
    
            System.out.println("---");
    
            System.out.println("Checking obj2:");
            // Check if obj2 is an instance of Printable
            if (obj2 instanceof Printable) {
                System.out.println("obj2 implements Printable");
                // Printable p2 = (Printable) obj2; // Would cause ClassCastException
                // p2.print();
            } else {
                System.out.println("obj2 does not implement Printable");
            }
    
            // Check if obj2 is an instance of Editable
            if (obj2 instanceof Editable) {
                System.out.println("obj2 implements Editable");
                // Editable e2 = (Editable) obj2; // Would cause ClassCastException
                // e2.edit("Some Content");
            } else {
                System.out.println("obj2 does not implement Editable");
            }
        }
    }

    In this updated code, we now check if obj1 is an instance of both Printable and Editable. Since Document implements both, both if conditions for obj1 will be true. We also demonstrate calling the edit() method after casting to Editable. For obj2 (the String), both checks will be false.

  3. Save the file.

Finally, compile and run the updated code.

  1. Open the Terminal in the ~/project directory.

  2. Compile the Java files again:

    javac Printable.java Editable.java Document.java InterfaceCheck.java
  3. Run the InterfaceCheck program:

    java InterfaceCheck

    You should see output similar to this:

    Checking obj1:
    obj1 implements Printable
    Printing Document: Initial Content
    obj1 implements Editable
    Document edited.
    Printing Document: Modified Content
    ---
    Checking obj2:
    obj2 does not implement Printable
    obj2 does not implement Editable

This output shows that instanceof correctly identified that the Document object (obj1) implements both interfaces, and we were able to cast and call methods from both Printable and Editable. The String object (obj2) correctly showed that it implements neither.

Handle Null and Non-Implementing Objects

In this step, we will examine how the instanceof keyword behaves when dealing with null references and objects that do not implement the interface being checked. Understanding these cases is important for writing robust code.

Let's modify our InterfaceCheck.java file to include a null reference and an object of a class that does not implement either Printable or Editable.

  1. Open the InterfaceCheck.java file in the ~/project directory.

  2. Replace the existing code with the following:

    package project;
    
    // Assume Printable and Editable interfaces and Document class are already defined
    
    public class InterfaceCheck {
        public static void main(String[] args) {
            Object obj1 = new Document("Initial Content");
            Object obj2 = "Just a String"; // Does not implement Printable or Editable
            Object obj3 = null; // A null reference
            Object obj4 = new Object(); // An object that does not implement Printable or Editable
    
            System.out.println("Checking obj1 (Document):");
            if (obj1 instanceof Printable) {
                System.out.println("obj1 implements Printable");
            } else {
                System.out.println("obj1 does not implement Printable");
            }
            if (obj1 instanceof Editable) {
                System.out.println("obj1 implements Editable");
            } else {
                System.out.println("obj1 does not implement Editable");
            }
    
            System.out.println("---");
    
            System.out.println("Checking obj2 (String):");
            if (obj2 instanceof Printable) {
                System.out.println("obj2 implements Printable");
            } else {
                System.out.println("obj2 does not implement Printable");
            }
            if (obj2 instanceof Editable) {
                System.out.println("obj2 implements Editable");
            } else {
                System.out.println("obj2 does not implement Editable");
            }
    
            System.out.println("---");
    
            System.out.println("Checking obj3 (null):");
            if (obj3 instanceof Printable) {
                System.out.println("obj3 implements Printable");
            } else {
                System.out.println("obj3 does not implement Printable");
            }
            if (obj3 instanceof Editable) {
                System.out.println("obj3 implements Editable");
            } else {
                System.out.println("obj3 does not implement Editable");
            }
    
            System.out.println("---");
    
            System.out.println("Checking obj4 (Object):");
            if (obj4 instanceof Printable) {
                System.out.println("obj4 implements Printable");
            } else {
                System.out.println("obj4 does not implement Printable");
            }
            if (obj4 instanceof Editable) {
                System.out.println("obj4 implements Editable");
            } else {
                System.out.println("obj4 does not implement Editable");
            }
        }
    }

    In this updated code, we've added two new Object variables:

    • obj3 is assigned null.
    • obj4 is assigned a new instance of the base Object class, which does not implement our custom interfaces.

    We then use instanceof to check each of these objects against both Printable and Editable.

  3. Save the file.

Now, let's compile and run the updated code.

  1. Open the Terminal in the ~/project directory.

  2. Compile the Java files. Since we only modified InterfaceCheck.java, we can compile just that file, but compiling all three is also fine:

    javac Printable.java Editable.java Document.java InterfaceCheck.java
  3. Run the InterfaceCheck program:

    java InterfaceCheck

    You should see output similar to this:

    Checking obj1 (Document):
    obj1 implements Printable
    obj1 implements Editable
    ---
    Checking obj2 (String):
    obj2 does not implement Printable
    obj2 does not implement Editable
    ---
    Checking obj3 (null):
    obj3 does not implement Printable
    obj3 does not implement Editable
    ---
    Checking obj4 (Object):
    obj4 does not implement Printable
    obj4 does not implement Editable

Observe the output for obj3 (the null reference). The instanceof operator returns false when the object reference is null, regardless of the type being checked. This is a key behavior of instanceof and prevents NullPointerException errors when performing the check.

Also, observe the output for obj4 (the plain Object). As expected, since the Object class does not implement Printable or Editable, the instanceof checks return false.

This step demonstrates that instanceof is safe to use with null references and correctly identifies objects that do not implement the specified interface.

Summary

In this lab, we learned how to check if an object implements a specific interface in Java using the instanceof keyword. We started by defining a simple interface (Printable) and a class (Document) that implements it. We then created a main class (InterfaceCheck) to demonstrate how to use instanceof to verify if an object is an instance of the Printable interface. This fundamental technique is crucial for safely casting objects and calling interface-specific methods.

We further explored the flexibility of instanceof by testing objects that implement multiple interfaces and also considered edge cases such as handling null objects and objects that do not implement the target interface. This comprehensive approach ensures a robust understanding of how to reliably determine an object's interface implementation status in various scenarios.