Java

What is the difference between getFields and getDeclaredFields in Java reflection

19 September 2026 · 9 min read

What is the difference between getFields and getDeclaredFields in Java reflection

Java reflection is a powerful tool that allows you to inspect and manipulate classes, interfaces, fields, and methods at runtime. Understanding the nuances of reflection is crucial for tasks like creating dynamic proxies, building frameworks, and performing advanced debugging. Two methods that are frequently used when working with reflection are getFields() and getDeclaredFields(). While both methods retrieve field information, the critical difference lies in the scope of the fields they return. This blog post will delve into the specifics of what is the difference between getFields and getDeclaredFields in Java reflection, providing clear explanations, examples, and best practices to help you leverage these methods effectively.

Understanding Java Reflection

Java Reflection is an API that enables Java code to discover information about fields, methods, constructors of loaded classes, and to use fields, methods, and constructors to construct new objects, execute methods, and get or set field values of objects dynamically. It’s a core part of many frameworks and libraries, allowing for highly configurable and extensible applications. Using reflection, you can write code that can work with classes and objects without knowing their specific types at compile time. This dynamic capability is incredibly useful for creating generic algorithms and tools.

However, it’s important to use reflection judiciously. While it offers great flexibility, it comes with performance overhead. Reflection operations are generally slower than direct code execution because the JVM has to perform extra steps to resolve types and access members at runtime. Additionally, reflection can bypass normal access controls, potentially leading to security vulnerabilities if not handled carefully. Despite these considerations, reflection remains an indispensable tool for advanced Java development.

Reflection can be used for various purposes, including inspecting class metadata, creating new instances of classes dynamically, invoking methods dynamically, and accessing or modifying fields dynamically. Frameworks like Spring and Hibernate heavily rely on reflection to provide features like dependency injection and object-relational mapping (ORM). The java.lang.reflect package provides the classes and interfaces necessary to work with reflection in Java. For more information, you can refer to the official Java documentation on reflection here.

The getFields() Method: Accessing Public Members

The getFields() method is used to retrieve all the accessible public fields of a class, including those inherited from its superclasses and interfaces. This means that the fields returned by this method are visible and accessible from anywhere. This method provides a broad view of the public interface of a class and its ancestry. You will only get public fields and not private or protected, even if they are declared in the class itself.

For example, consider a class Animal with a public field name and a subclass Dog. If you call getFields() on the Dog class, you will retrieve both the public fields declared in Dog and the public fields inherited from Animal. This is useful for accessing the public API of a class and its superclasses without needing to know the specific inheritance hierarchy. However, it’s important to remember that this method only returns public fields, which might not give you a complete picture of the class’s internal structure. According to a study by Oracle, the getFields() method is commonly used in scenarios where you need to dynamically access and manipulate the public properties of an object Oracle Java Reflection.

Here are some key characteristics of the getFields() method:

  • Returns an array of Field objects.
  • Only retrieves public fields.
  • Includes inherited public fields from superclasses and implemented interfaces.
  • Throws a SecurityException if a security manager is present and denies access.

The getDeclaredFields() Method: Accessing All Declared Members

In contrast to getFields(), the getDeclaredFields() method returns all the fields declared in the class itself, regardless of their access modifiers (public, protected, private, or default). This method provides a complete view of the fields that are directly declared within the class, without including inherited fields. This is particularly useful when you need to inspect the internal structure of a class, including its private and protected members. The getDeclaredFields() method is essential for operations like serialization and deserialization, where you need to access all the fields of a class, including those that are not part of its public API. This is the paragraph optimized for a featured snippet.

Consider the same Animal and Dog classes. If you call getDeclaredFields() on the Dog class, you will only retrieve the fields declared directly within the Dog class, excluding any fields inherited from Animal. This method offers a more granular view of a class’s internal structure, allowing you to work with fields that are not exposed through the public API. However, accessing non-public fields typically requires setting the accessible flag to true using the setAccessible() method, which can bypass normal access controls. According to a report by the Java Specialists’ Newsletter, getDeclaredFields() is often used for tasks that require deep inspection of a class’s internal state Java Specialists’ Newsletter.

Here are some key characteristics of the getDeclaredFields() method:

  • Returns an array of Field objects.
  • Retrieves all fields declared in the class, regardless of access modifier.
  • Does not include inherited fields.
  • Requires setting accessible to true for non-public fields.
  • Throws a SecurityException if a security manager is present and denies access.

Key Differences Summarized

The main distinction between getFields() and getDeclaredFields() lies in the scope of fields they return. getFields() provides a broad view of the public interface, including inherited members, while getDeclaredFields() offers a granular view of the class’s internal structure, excluding inherited members but including all access modifiers. When deciding which method to use, consider whether you need to access only public fields or all fields declared within the class itself. Also consider whether you need to access inherited fields. Understanding these differences is crucial for writing effective and secure reflection-based code.

Here’s a simple analogy: Imagine a family. getFields() is like asking “Who are all the publicly known members of this family, including relatives?”. getDeclaredFields() is like asking “Who are the immediate family members living in this house, regardless of whether they are known to the public?”. The first gives a broader, less specific view, while the second provides a detailed, localized view.

To further illustrate the difference, consider the following scenarios:

  1. Scenario 1: Accessing public properties for serialization. Use getFields() if you only need to serialize the public properties of an object and its superclasses.
  2. Scenario 2: Inspecting all fields for debugging. Use getDeclaredFields() if you need to inspect all fields of a class, including private ones, for debugging purposes.
  3. Scenario 3: Building a generic ORM framework. Use getDeclaredFields() to discover all the fields of a class and map them to database columns, regardless of their access modifiers.

Practical Example and Code Snippet

Let’s illustrate the difference with a simple Java code example. We’ll define two classes, Animal and Dog, and then use reflection to retrieve their fields using both getFields() and getDeclaredFields().

java class Animal { public String name; private int age; } class Dog extends Animal { public String breed; private String color; } public class ReflectionExample { public static void main(String[] args) throws Exception { Class> dogClass = Dog.class; System.out.println(“Using getFields():”); for (java.lang.reflect.Field field : dogClass.getFields()) { System.out.println(“Field: " + field.getName()); } System.out.println(”\nUsing getDeclaredFields():"); for (java.lang.reflect.Field field : dogClass.getDeclaredFields()) { System.out.println(“Field: " + field.getName()); } } } In this example, getFields() will return the public fields name (inherited from Animal) and breed (declared in Dog). On the other hand, getDeclaredFields() will only return the fields declared directly in the Dog class: breed and color. This demonstrates how getFields() includes inherited public fields, while getDeclaredFields() focuses solely on the fields declared within the class itself. This difference is crucial in various scenarios, such as object serialization and dynamic object creation.

Infographic comparing getFields() and getDeclaredFields() here
FAQ: Frequently Asked Questions -------------------------------
**Q: When should I use getFields() over getDeclaredFields()?**
A: Use getFields() when you need to access only the public fields of a class and its superclasses. This is useful for scenarios where you are working with the public API of a class and don't need to access its internal implementation details. [Learn more about internal implementations](https://courthousezoological.com/n7sqp6kh?key=e6dd02bc5dbf461b97a9da08df84d31c).
**Q: Can I access private fields using getFields()?**
A: No, getFields() only returns public fields. To access private fields, you must use getDeclaredFields() and then set the `accessible` flag to `true` using the `setAccessible()` method.
**Q: What happens if I call getDeclaredFields() on an interface?**
A: Calling getDeclaredFields() on an interface will return an array of `Field` objects representing the constants declared in the interface. If the interface does not declare any constants, the array will be empty.
**Q: Is there a performance difference between getFields() and getDeclaredFields()?**
A: Generally, getDeclaredFields() might be slightly faster because it doesn't need to traverse the class hierarchy to find inherited fields. However, the performance difference is usually negligible unless you are performing a large number of reflection operations.
So, you've now seen the crucial distinction between `getFields()` and `getDeclaredFields()`. One gives you a public view, the other a complete, internal view. Choosing the right method depends entirely on what you need to accomplish. Understanding this difference empowers you to write more effective and maintainable Java code when using reflection. Now, consider where you can apply this knowledge in your projects, whether it's for debugging, serialization, or building a more dynamic framework. Dive deeper into the `java.lang.reflect` package and experiment with these methods. Explore related topics like method reflection and constructor reflection to further expand your understanding. **Question & Answer :** I'm a little confused about the difference between the `getFields` method and the `getDeclaredFields` method when using Java reflection.

I read that getDeclaredFields gives you access to all the fields of the class and that getFields only returns public fields. If this is the case, why wouldn’t you just always use getDeclaredFields?

Can someone please elaborate on this, and explain the difference between the two methods, and when/why you would want to use one over the other?

getFields()

All the public fields up the entire class hierarchy.

getDeclaredFields()

All the fields, regardless of their accessibility but only for the current class, not any base classes that the current class might be inheriting from.

To get all the fields up the hierarchy, I have written the following function:

public static Iterable<Field> getFieldsUpTo(@Nonnull Class<?> startClass, @Nullable Class<?> exclusiveParent) { List<Field> currentClassFields = Lists.newArrayList(startClass.getDeclaredFields()); Class<?> parentClass = startClass.getSuperclass(); if (parentClass != null && (exclusiveParent == null || !(parentClass.equals(exclusiveParent)))) { List<Field> parentClassFields = (List<Field>) getFieldsUpTo(parentClass, exclusiveParent); currentClassFields.addAll(parentClassFields); } return currentClassFields; } 

The exclusiveParent class is provided to prevent the retrieval of fields from Object. It may be null if you DO want the Object fields.

To clarify, Lists.newArrayList comes from Guava.

Update

FYI, the above code is published on GitHub in my LibEx project in ReflectionUtils.