Updated your writeInLogger method. I also added to check for the write method, else you get Class also as a property and the stack blows.

private static void writeInLogger(Object obj, String str) {
    Class klazz = obj.getClass();
    if (klazz.isPrimitive() || obj instanceof String || obj instanceof Integer || obj instanceof Double
            || obj instanceof Boolean)
        System.out.println(str + obj.toString());
    else {
        try {
            for (PropertyDescriptor propertyDescriptor : Introspector.getBeanInfo(klazz).getPropertyDescriptors()) {
                if(propertyDescriptor.getWriteMethod() == null)
                    continue;
                Method m = propertyDescriptor.getReadMethod();
                if (m != null) {
                    Object object = m.invoke(obj);
                    if(object != null)
                        writeInLogger(object, str);
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IntrospectionException e) {
            e.printStackTrace();
        }
    }
}
Answer from Dakshinamurthy Karra on Stack Overflow
🌐
Baeldung
baeldung.com › home › java › core java › retrieve fields from a java class using reflection
Retrieve Fields from a Java Class Using Reflection | Baeldung
January 4, 2026 - List<Field> personFields = Arrays.asList(Employee.class.getSuperclass().getDeclaredFields()); List<Field> employeeFields = Arrays.asList(Employee.class.getDeclaredFields()); List<Field> allFields = Stream.concat(personFields.stream(), employeeFields.stream()) .collect(Collectors.toList()); assertEquals(4, allFields.size()); Field lastNameField = allFields.stream() .filter(field -> field.getName().equals(LAST_NAME_FIELD)) .findFirst().orElseThrow(() -> new RuntimeException("Field not found")); assertEquals(String.class, lastNameField.getType()); Field firstNameField = allFields.stream() .filter
Top answer
1 of 2
4

Updated your writeInLogger method. I also added to check for the write method, else you get Class also as a property and the stack blows.

private static void writeInLogger(Object obj, String str) {
    Class klazz = obj.getClass();
    if (klazz.isPrimitive() || obj instanceof String || obj instanceof Integer || obj instanceof Double
            || obj instanceof Boolean)
        System.out.println(str + obj.toString());
    else {
        try {
            for (PropertyDescriptor propertyDescriptor : Introspector.getBeanInfo(klazz).getPropertyDescriptors()) {
                if(propertyDescriptor.getWriteMethod() == null)
                    continue;
                Method m = propertyDescriptor.getReadMethod();
                if (m != null) {
                    Object object = m.invoke(obj);
                    if(object != null)
                        writeInLogger(object, str);
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IntrospectionException e) {
            e.printStackTrace();
        }
    }
}
2 of 2
1
private static void writeInLogger(Object obj, String str) {
        if (obj == null) {
             System.out.println(str + "null");
             return;
        }
        Class klazz = obj.getClass();        
        if (klazz.isPrimitive() || obj instanceof String
                || obj instanceof Integer || obj instanceof Double
                || obj instanceof Boolean)
            System.out.println(str + obj.toString());
        else {
            try {
                for (Field field : klazz.getDeclaredFields()) {
                    field.setAccessible(true);
                    Object f = field.get(obj);
                    field.setAccessible(false);
                    writeInLogger(f, str);
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (IntrospectionException e) {
                e.printStackTrace();
            }
        }
}

Browse all fields in class and get the value object as the writeInLogger parameter.

getFields() only get public fields, getDeclaredFields to get all fields in class.

🌐
Coderanch
coderanch.com › t › 386252 › java › Recursive-Reflection-method
Recursive Reflection method (Java in General forum at Coderanch)
September 23, 2008 - It would be something like this: That loop will make sure you get all fields, also those of the super classes.
🌐
GitHub
gist.github.com › 11279105
FieldUtils mutates and accesses fields using reflection. · GitHub
FieldUtils mutates and accesses fields using reflection. - FieldUtils.java
🌐
Codez Up
codezup.com › home › recursively modify object values reflection java
Recursively Modify Object Values Reflection Java | Codez Up
April 12, 2021 - We will create a simple custom annotation and mark all the object fields which need to modify at runtime by using reflection with this annotation. ... package com.modifyobject; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface ModifyFields { }
🌐
Coderanch
coderanch.com › t › 379321 › java › iterate-List-type-property-objects
iterate to all List type property of my objects recursively (Java in General forum at Coderanch)
March 6, 2006 - Hi, maybe some expert in reflection can help me with my problem. i need a way to access a List property on my object, but this must also recursively parse any List property it may find on the List Object. just a simple traversing with system.out will do. please help. thanks. ... Look into reflection, ie using the methods on the Class class. Look at the JavaDoc for Class getFields() and getDeclaredFields(). Many frameworks that convert objects to XML or move objects in and out of databases use these tricks to get and set fields.
Find elsewhere
🌐
Ideyatech
ideyatech.com › blog › 2011 › 05 › 28 › retrieving-values-using-java-reflection
Coder Tip on How To Recursively Retrieve Values Using Java Reflection
June 10, 2015 - So, here’s the piece of code that allows you to recursively retrieve object values through a standard Java object notation (e.g. employee.name, employee.office.location) that we have used for the features described above: public static Object retrieveObjectValue(Object obj, String property) { if (property.contains(".")) { // we need to recurse down to final object String props[] = property.split("\\."); try { Object ivalue = null; if (Map.class.isAssignableFrom(obj.getClass())) { Map map = (Map) obj; ivalue = map.get(props[0]); } else { Method method = obj.getClass().getMethod(getGetterMetho
🌐
Posts Games
postsgames.com › home › java reflection get all fields recursively
Java Reflection Get All Fields Recursively latest game news, video games Nov-2021
Jun 12, 2020 · This recursive method will search public and protected fields through the cla*s hierarchy and returns all that have been found in a List. Let's ... ... Did you know that the results of 'Java Reflection Get All Fields Recursively' are collated and compared from the tens of millions of different outcomes that can be found on the Internet?
🌐
GitHub
github.com › Aliuken › JavaObjectPrinter
GitHub - Aliuken/JavaObjectPrinter: Print the value of a given Java object by using reflection recursively.
"I have created a project called JavaObjectPrinter on GitHub which uses reflection and looks for the non-static attributes that have getter recursively (until a given depth) and creates a HTML file with a table for each class having a column for each attribute and a file for each instanced object of the class. It also groups the duplicated objects found." This answer was deleted however from the following questions: How to list all properties exposed by a Java class and its ancestors in Eclipse?
Author   Aliuken
🌐
Baeldung
baeldung.com › home › java › core java › get all record fields and its values via reflection
Get All Record Fields and Its Values via Reflection | Baeldung
January 16, 2024 - However, the problem can be solved without using the new RecordComponent class. Java reflection API provides the Class.getDeclaredFields() method to get all declared fields in the class.
🌐
10duke
developer.10duke.com › sdk › APIDoc › com › tenduke › sdk2 › utils › reflection › ReflectionUtils.html
ReflectionUtils (sdk2-build 2.0.8-SNAPSHOT API)
public static List<Field> getFields(Class objectClass, boolean recursive) Returns recursively list containing all fields of a class.
Top answer
1 of 4
3

To recursively modify all fields in an object annotated with a given annotation we have to determine first all fields.

Class.getFields() will return only "accessible public fields". This doesn't match the requirement. Therefore we have to use Class.getDeclaredFields(). This in turn returns only the fields "declared by the class". In order to get all fields we have to traverse the type hierarchy of a target object upwards and process for each type its declared fields.

For every field we have to distinguish some cases:

  1. A Field is annotated with the specified annotation. Then the given value has to be applied to the field. In order to set the value, the field has to be (made) accessible and non final.
  2. A Field is not annotated with the specified annotation. Then there are three cases to distinguish:
    • The field has a primitive type. Then it isn't an object, which could contain a String field.
    • The field has an array type. Then it cannot contain a String field.
    • Else: The field has a reference type. Then it has to be (made) accessible, to check if it has a value set and in this case to process its fields recursively for 1) and 2) again.

To check whether an annotation is set on a field, we use Field.getAnnotation(myAnnotationClass) where myAnnotationClass is declared as Class<MyAnnotation>. But we have to be aware of something additional:
Field.getAnnotation(myAnnotationClass) will return the fields's annotation only if

  • it's set (quite self-explanatory)
  • MyAnnotation itself is annotated with @Retention(RetentionPolicy.RUNTIME).

The corresponding code would look like that:

  public static <T extends Annotation> void setValueOnAnnotatedFields(String s, Class<T> annotationClass, Object target) {
    if (target != null) {
      // traversing the type hierarchy upward to process fields declared in classes target's class extends
      Class<?> clazz = target.getClass();
      do {
        setValueOnAnnotatedDeclaredFields(s, annotationClass, target, clazz);
      }
      while ((clazz = clazz.getSuperclass()) != null);
    }
  }

  private static <T extends Annotation> void setValueOnAnnotatedDeclaredFields(String s, Class<T> annotationClass, Object target, Class<?> clazz) {
    Field[] fields = clazz.getDeclaredFields();
    for (Field field : fields) {
      if (field.getAnnotation(annotationClass) != null) {
        set(field, target, s);
      } else if (!field.getType().isPrimitive() && !field.getType().isArray()) {
        setValueOnAnnotatedFields(s, annotationClass, get(field, target));
      }
    }
  }

  protected static void set(Field field, Object target, String value) {
    try {
      makeFiieldAccessibleNotFinal(field, target);
      field.set(target, value);
    }
    catch (Exception e) {
      String message = String.format("Failed to set the value on field %s", target.getClass().getSimpleName() + "." + field.getName());
      throw new IllegalStateException(message, e);
    }
  }

  protected static Object get(Field field, Object target) {
    try {
      makeFiieldAccessibleNotFinal(field, target);
      return field.get(target);
    }
    catch (Exception e) {
      String message = String.format("Failed to get the value on field %s", target.getClass().getSimpleName() + "." + field.getName());
      throw new IllegalStateException(message, e);
    }
  }

  protected static void makeFiieldAccessibleNotFinal(Field field, Object target) {
    try {
      Field modifiersField = Field.class.getDeclaredField("modifiers");
      modifiersField.setAccessible(true);
      modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
    }
    catch (Exception e) {
      String message = String.format("Failed to remove final declaration of field %s", field.getName());
      throw new IllegalStateException(message, e);
    }
    try {
      field.setAccessible(true);
    }
    catch (Exception e) {
      String message = String.format("Failed to make field %s accessible", field.getName());
      throw new IllegalStateException(message, e);
    }
  }

An example:

  public static void main(String[] args) {
    A a = new A();
    System.out.println(a); // s: null / b: [null]

    setValueOnAnnotatedFields("1", MyAnnotation.class, a);
    System.out.println(a); // s: 1 / b: [null]

    a.b = new B();
    setValueOnAnnotatedFields("2", MyAnnotation.class, a);
    System.out.println(a); // s: 2 / b: [a: 2 / b: null]
  }

This implies class A to have toString() implemented like that:

@Override
public String toString() {
  return "s: " + s + " / b: [" + Optional.ofNullable(b).map(B::toString).orElse("null") + "]";
}

And class B to have toString() implemented like that:

@Override
public String toString() {
  return "a: " + a + " / b: " + b;
}
2 of 4
0

You can use Java reflection API to inspect the fields of your class:

Get the declared annotations foreach field;

Check if you have your annotation..

Well, it is not a difficult thing to do thanks to Reflection API.

🌐
Asgteach
asgteach.com › 2012 › 11 › navigating-class-hierarchies-with-java-reflection
Navigating Class Hierarchies with Java Reflection | Anderson Software Group, Inc.
November 6, 2012 - Let’s write a Java Reflection program to navigate through this class hierarchy and print out the class and package names. We’ll write this program specifically for the JTextField class, but you should be able to easily adapt it to access class names in the inheritance hierarchy of any Java class. Our program needs the getSuperclass() and getName() methods from the Java Reflection API.
🌐
Coderanch
coderanch.com › t › 373499 › java › reflection-fields-public
Using reflection to get ALL fields, not just public ones (Java in General forum at Coderanch)
Certainly, that's exactly what the API Spec says it does, but it's not what I'm after. Instead, I really want all fields contained by Child - that should include one, two, four, five, and six. I've also looked at using getDeclaredFields(), but that only returns the fields declared within Child and skips those that are inherited from Parent.