Java's Object Methods: getClass()

Introduction

This article is a continuation of a series of articles describing the often forgotten about methods of the Java language's base Object class. Below are the methods of the base Java Object present in all Java objects due to the implicit inheritance of Object along with links to each article of this series.

  • toString
  • getClass (you are here)
  • equals
  • hashCode
  • clone
  • finalize
  • wait & notify

The focus of this article is the getClass() method, which is used to access metadata about the class of the object your are working with.

The getClass() Method

The somewhat confusing or misunderstood Object method getClass() returns an instance of the Class class, which contains information about the class that getClass() was called from. Whew, if your not confused already by that last statement good for you, because I am and I wrote it!

Let me try to unpack that sentence with a demonstration of how this might be used. Below you will find the Person class I used in the initial article on the Object class's toString() method.

package com.adammcquistan.object;

import java.time.LocalDate;

public class Person {  
    private String firstName;
    private String lastName;
    private LocalDate dob;

    public Person(String firstName, String lastName, LocalDate dob) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.dob = dob;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public LocalDate getDob() {
        return dob;
    }

    public void setDob(LocalDate dob) {
        this.dob = dob;
    }

    @Override
    public String toString() {
        return "<Person: firstName=" + firstName + ", lastName=" + lastName + ", dob=" + dob + ">";
    }
}

Let's focus in on the overridden toString() method, which lists the name of the class, Person, along with the values of the instance's fields. Instead of "hard-coding" the name of the class, Person, in the string itself I could have actually used the getClass() method to return an instance of the Class class, which will contain that info and allow me to use it like so:

public class Person {  
    // omitting everyting else remaining the same

    @Override
    public String toString() {
        Class c = getClass();
        return "<" + c.getName() + ": firstName=" + firstName + ", lastName=" + lastName + ", dob=" + dob + ">";
    }
}

This would lead to replacing the original hard-coded "Person" text with the fully qualified class name of "com.adammcquistan.object.Person". The Class class is packed full of different methods that allow you to identify all kinds of things about the class object that getClass() was called on.

For example, if I wanted to get a more simplified toString() representation of my Person class I could simply swap out the c.getName() call with c.getSimpleName() like shown below. This in turn would return "Person" instead of the fully qualified class name "com.adammcquistan.object.Person".

public class Person {  
    // omitting everyting else remaining the same

    @Override
    public String toString() {
        Class c = getClass();
        return "<" + c.getSimpleName() + ": firstName=" + firstName + ", lastName=" + lastName + ", dob=" + dob + ">";
    }
}

A major difference in the semantics of how getClass() is used in comparison to the other Object methods is that getClass() cannot be overriden because it is declared as a final method.

What is the Class object Good For?

At this point you may be asking yourself, "Ok I guess it is pretty cool that I can get information about a class by calling getClass() and retrieving its Class object representation, but how is this useful to me as a programmer?". Believe me, I've asked myself this question as well and my general conclusion has been... it's not. At least it is not really from an everyday programmer's perspective. However, if you happen to be a library or framework developer then you are likely to get very familiar with the information and behavior of Class objects because it is essential for the concept known as reflection.

Reflection allows for two primary things: (i) runtime investigation of objects and their contents and, (ii) dynamic access to fields and execution of methods during runtime.

Item number one was already demonstrated above by using getClass() to get a runtime representation of the Person class to access either the fully qualified or simple class name in a modified version of the toString() method.

The second item is a bit more involved to whip up an example for, but it is something that is quite helpful to be able to access metadata on a class. Some of the information that you can interrogate an instance of Class for are things like constructors, fields, and methods plus other things like inheritance hierarchies of a class, like it's super classes and interfaces.

An example of this is the ability to use debuggers in an IDE like Eclipse and Netbeans to see the member's and their values in a class while the program is in execution.

Take for example the following:

public class Main {  
    public static void main(String[] args) {
        Person me = new Person("Adam", "McQuistan", LocalDate.parse("1987-09-23"));

        Class c = me.getClass();
        for (Field f : c.getDeclaredFields()) {
            f.setAccessible(true);
            try {
                System.out.println(f.getName() + " = " + f.get(me));
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }
}

Would output the following:

firstName = Adam  
lastName = McQuistan  
dob = 1987-09-23  

Again, no non-masochist would probably ever do this in regular everyday programming, but you will see this type of thing done often in frameworks.

Conclusion

In this article I described the meaning and use of the mysterious getClass() method of the Java Object class. I have shown how it can be used to get metadata on a class instance such as the name of the class of an object at runtime as well as provided an explanation of why accessing a Class instance may be useful.

As always, thanks for reading and don't be shy about commenting or critiquing below.

Author image
Lincoln, Nebraska Twitter