3 min read

Class and Interface Reflection in Java

Class and interface reflection is a way to obtain metadata at runtime.
Class and Interface Reflection in Java

What is Class and Interface Reflection?

Most of this article will focus on class reflection. Whether you are working with class reflection or interface reflection, they are mostly the same.

Class reflection is a runtime feature that allows you to obtain information about a class. Some of the information that can be obtained is what interfaces it implements, what the permitted classes are on a sealed class, the name of the class, and much more.

Class and Interface Reflection

The examples in this section will use the following class.

package press.bytesize;

public class User extend DaoObject {
}

Obtaining Instances

In order to use class reflection, you must first obtain an instance of a Class. The Class object is a singleton instance. You obtain the instance using the following:

final Class<User> userClass = User.class;

Class or Interface Name

You can get the name of the class or interface using the getSimpleName() method.

// Prints: User
System.out.println(User.class.getSimpleName());

This returns only the name of the class or interface. If you need the fully qualified class name or interface name, you can use the getName() method instead.

// Prints: press.bytesize.User
System.out.println(User.class.getName());

Superclass Information

When working with reflection, the information obtained mirrors the Java class file and not the object you work with in code. Because of this, if you have a superclass and need to access the reflection metadata in that superclass, you do so using the getSuperclass() method.

final Class<?> superclass = User.class.getSuperclass();

Both this method and the following method would return the same Class instance.

final Class<DaoObject> daoObjectClass = DaoObject.class;

Modifiers

You can find out what modifiers a class has using the getModifiers() method. This method returns an int. You can then use the java.lang.Modifier class to see if a class has a specific modifier.

final int modifiers = User.class.getModifiers();

System.out.println(Modifier.isPublic(modifiers)); // true
System.out.println(Modifier.isFinal(modifiers));  // false

Java 20 introduced the accessFlags() method. This returns a java.util.Set of java.lang.reflect.AccessFlags. You can then check to see if the Set contains an AccessFlag.

final Set<AccessFlag> flags = User.class.accessFlags();

System.out.println(flags.contains(AccessFlag.PUBLIC)); // true
System.out.println(flags.contains(AccessFlag.FINAL));  // false

Interfaces

Classes can implement zero or more interfaces, and interfaces can extend zero or more interfaces. To get the interfaces a class implements or the interfaces that an interface extends, you can use the getInterfaces() method.

final Class<?>[] interfaces = User.class.getInterfaces();

Since the User class doesn't implement any interfaces, this will return an empty array.

You can also check to see if the Class is an interface. This is done through the isInterface() method. This will return true if it is an interface and false if it isn't.

final boolean isInterface = User.class.isInterface();

Sealed Classes

A sealed class has a sealed keyword and a permits clause. You can obtain the classes that are permitted to be extended by this class using the getPermittedSubclasses() method. This returns an array of Class objects that are declared in the permits clause.

final Class<?>[] permittedClasses = User.class.getPermittedSubclasses();

If the class doesn't have a permits clause, the getPermittedSubclasses() method will return null.

You can check if a class is sealed with the isSealed() method. This returns true if it is sealed and false if it isn't.

final boolean isSealed = User.class.isSealed();

Enumeration Classes

Enumerations are a special type of class that extends java.lang.Enum. You can get each enumeration constant using the getEnumConstants() method.

public enum Color {
    RED,
    YELLOW,
    GREEN;
}

for (final Color color : Color.class.getEnumConstants()) {
    System.out.println(color.name());
}

This will produce the following output:

RED
YELLOW
GREEN

If the getEnumConstants() method is called on a class that isn't an enumeration, this method will return null. The getEnumConstants() is similar to the values() method on an enumeration. If this is what you are trying to do, use the values() method instead of reflection.

You can check to see if a class is an enumeration with the isEnum() method.

final boolean isEnum = Color.class.isEnum();

This will return true if the class is an enumeration and false if it isn't.

Conclusion

Class reflection allows you to obtain metadata about a class at runtime. It can be used to obtain information such as the interfaces it implements, the modifiers defined on the class, and many pieces of data.