Explain Codes LogoExplain Codes Logo

Retrieving the inherited attribute names/values using Java Reflection

java
reflection
field-utils
apache-commons-lang
Alex KataevbyAlex Kataev·Oct 7, 2024
TLDR

You can procure public and non-public fields of an object and its superclasses using Java Reflection. Just stroll up the class hierarchy with getDeclaredFields and set them accessible.

Object obj = // ... inauguration day, let the object instance step in Class<?> cls = obj.getClass(); while (cls != null) { for (Field field : cls.getDeclaredFields()) { field.setAccessible(true); // No field left behind! Let's pry open those private/protected ones System.out.println(field.getName() + ": " + field.get(obj)); } cls = cls.getSuperclass(); // Keep climbing up the family tree }

This snippet declaims every single field name and value, including ones passed down from ancestors, for the specified object (obj). Keep an eye out for IllegalAccessException when attempting to access fields.

Fine-tuning field retrieval

The fast answer cruises to the destination, but let's slow down and take a scenic route. Parsing the fields from classes and superclasses, and storing them for further usage.

Gathering all fields in a list

Here's a public static method to not just print but collect fields:

public static List<Field> getAllFields(List<Field> fields, Class<?> type) { fields.addAll(Arrays.asList(type.getDeclaredFields())); // Collecting all our belongings if (type.getSuperclass() != null) { // As long as there's an ancestor fields = getAllFields(fields, type.getSuperclass()); // Recursion, Ah! sweet inheritance } return fields; // Can't return empty-handed, can we now? }

The Apache Way

Save the day using FieldUtils.getAllFieldsList from Apache Commons Lang (version 3.2+ required), to avoid the hustle:

List<Field> allFields = FieldUtils.getAllFieldsList(obj.getClass()); allFields.forEach(field -> { field.setAccessible(true); System.out.println(field.getName()); // Field printout, coming right up! });

Don't forget the Test Drive

Put your code on a test bench before letting it out in the wild. Render it immune to quirks of complex class hierarchies and make sure it fetches all the fields.

Reflexivity with Generics

By using Class<?> in your code, you can ensure reusability and flexibility.

Avoid Redundancy

There's no need to reinvent the wheel. Reuse solutions from the Java community unless you can significantly spruce them up.

Accepting External Help

Don't shy away from external libraries like Apache Commons Lang. They reduce boilerplate code and ease reflection tasks.