What is the difference between getFields and getDeclaredFields in Java reflection
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Overview
Java Reflection is a powerful mechanism provided by the Java programming language that allows introspection and manipulation of classes, methods, fields, and other program elements at runtime. Two methods often used within this context for accessing class fields are getFields() and getDeclaredFields() from the java.lang.Class class. While they might seem similar at first glance, they serve different purposes and have distinct behaviors.
Understanding getFields()
The getFields() method returns an array containing Field objects reflecting all the accessible public fields of a class or interface, including those inherited from superclasses. Here's a breakdown of its key characteristics:
- Scope: It only retrieves public fields. Non-public fields (protected, package-private, or private) will not be included in the array returned by
getFields(). - Inheritance: The method also considers fields inherited from superclasses. This means that if a superclass has public fields, they will be included in the results.
Example:
In this example, getFields() retrieves both publicSuperField from the SuperClass and publicSubField from the SubClass.
Understanding getDeclaredFields()
In contrast, the getDeclaredFields() method provides a more comprehensive view of the fields within a class:
- Scope: It includes all fields declared by the class (irrespective of access level), meaning public, protected, package-private, and private fields are all included.
- Inheritance: Unlike
getFields(),getDeclaredFields()does not consider fields inherited from superclasses. It strictly returns fields that are declared directly within the class itself.
Example:
Here, getDeclaredFields() retrieves only the fields that are explicitly declared in SubClass, without considering those in any parent class.
Summary Table
| Aspect | getFields() | getDeclaredFields() |
| Access Level | Public fields only | All fields (public, protected, package, private) |
| Inheritance | Includes inherited fields | Excludes inherited fields |
| Visibility | Accesses only those fields visible to caller | Accesses all fields regardless of access level |
| Use Scenario | When public API exposure is needed or when working with inherited public fields | When full introspection of declared fields is critical |
Additional Considerations
- Security and Access Control: When using reflection, it's important to remember that by default, access checks are performed to ensure security. However, you can bypass these checks using
Field#setAccessible(true). Use this with caution. - Use Cases:
getFields()is typically used when working with APIs and frameworks that expose only the public part of an object, such as serialization mechanisms.getDeclaredFields()is more suited for deeper introspection tasks, like building tooling or frameworks that require detailed knowledge of the class structure.
- Performance Impact: Reflection in Java comes with performance costs, as it requires JVM to perform operations that are otherwise handled at compile time. Moreover, misusing reflection can break encapsulation and hinder optimization by the JVM.
In conclusion, both getFields() and getDeclaredFields() have distinct purposes and are chosen based on their respective use-cases and requirements. Understanding these differences allows developers to employ Java Reflection more effectively and safely.

