Java Reflection
getFields
getDeclaredFields
Java Programming
Reflection API

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:

java
1import java.lang.reflect.Field;
2
3class SuperClass {
4    public int publicSuperField;
5    private int privateSuperField;
6}
7
8class SubClass extends SuperClass {
9    public int publicSubField;
10}
11
12public class ReflectionDemo {
13    public static void main(String[] args) {
14        Field[] fields = SubClass.class.getFields();
15        for (Field field : fields) {
16            System.out.println(field.getName());
17        }
18        // Output:
19        // publicSuperField
20        // publicSubField
21    }
22}

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:

java
1import java.lang.reflect.Field;
2
3class SuperClass {
4    public int publicSuperField;
5    private int privateSuperField;
6}
7
8class SubClass extends SuperClass {
9    public int publicSubField;
10    private int privateSubField;
11}
12
13public class ReflectionDemo {
14    public static void main(String[] args) {
15        Field[] fields = SubClass.class.getDeclaredFields();
16        for (Field field : fields) {
17            System.out.println(field.getName());
18        }
19        // Output:
20        // publicSubField
21        // privateSubField
22    }
23}

Here, getDeclaredFields() retrieves only the fields that are explicitly declared in SubClass, without considering those in any parent class.

Summary Table

AspectgetFields()getDeclaredFields()
Access LevelPublic fields onlyAll fields (public, protected, package, private)
InheritanceIncludes inherited fieldsExcludes inherited fields
VisibilityAccesses only those fields visible to callerAccesses all fields regardless of access level
Use ScenarioWhen public API exposure is needed or when working with inherited public fieldsWhen 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.


Course illustration
Course illustration

All Rights Reserved.