What is the difference between getDeclaredFields()/getDeclaredMethods() and getFields()/getMethods() on a Java Class object?
answer
- Declared = all access, this class only
- Non-declared = public only, includes inherited
- No single call gives all-access + inherited
- Constructors are never inherited
- Listing != accessing — still need setAccessible
basics
~10 sgetDeclared* returns ALL members written in that one class (any access level) but nothing inherited. getFields/getMethods returns only PUBLIC members, including ones inherited from parent classes and interfaces.
solid answer
~40 sTwo axes differ. The "Declared" variants (getDeclaredFields, getDeclaredMethods, getDeclaredConstructors) return every member physically declared in that exact class regardless of visibility (private, package, protected, public) but they do NOT include inherited members. The non-declared variants (getFields, getMethods) return only public members, and they DO include public members inherited from superclasses and implemented interfaces. So Declared = all access levels, this class only; non-Declared = public only, this class plus ancestors. To reach a private inherited field you must walk up getSuperclass() calling getDeclaredField on each level. To call a non-public member you also need setAccessible(true). getMethods additionally includes the public methods of every implemented interface and Object's public methods.
code
java · 19 linesclass A { private int a; public int pubA;
private A() {} public A(int x) {} }
class B extends A { private int b; public int pubB; }
// All members of B itself, any access — NOT a/pubA from A
Field[] declared = B.class.getDeclaredFields(); // [b, pubB]
// Public members incl. inherited — pubA from A, pubB from B; NOT a or b
Field[] publicAll = B.class.getFields(); // [pubB, pubA]
// Walk up to collect every field, including private inherited ones
for (Class<?> c = B.class; c != null; c = c.getSuperclass()) {
for (Field f : c.getDeclaredFields()) {
f.setAccessible(true); // needed before reading non-public
System.out.println(c.getSimpleName() + "." + f.getName());
}
}
// Constructors are never inherited:
Constructor<?>[] ctors = B.class.getDeclaredConstructors(); // B's onlygo deeper
Can state the headline: getDeclared* = everything in this class regardless of visibility; getFields/getMethods = public only and include inherited members.
Articulates both axes (access level vs inheritance scope) cleanly and knows constructors aren't inherited; knows you still need setAccessible for non-public members.
Knows how to walk getSuperclass() to gather all inherited private members, that getMethods includes Object/interface methods, and that array order is unspecified.
Reasons about synthetic/bridge methods, module-system access constraints on setAccessible, performance of repeated reflective lookups (caching Member objects), and designing APIs that avoid leaking internals through reflection.
## What reflection is **Reflection** is Java's ability, at runtime, to look at the structure of classes and to read/modify/invoke their members without knowing them at compile time. Every loaded type has a runtime descriptor object of type `java.lang.Class`. From a `Class` object you can ask for its **members**: **fields** (variables), **methods** (functions), and **constructors** (the special methods that build instances). Each is returned as a reflection object: `Field`, `Method`, `Constructor`. ## The two independent axes The member-listing API splits along **two** separate questions, and confusion comes from mixing them up. **Axis 1 — Which access levels?** - A member's **access level** (also called visibility/modifier) is `public`, `protected`, package-private (no keyword), or `private`. - The methods whose name contains **`Declared`** ignore access level entirely: they return members of *every* visibility. - The methods *without* `Declared` return **only `public`** members. **Axis 2 — This class only, or inherited too?** - **Inheritance**: when class `B extends A`, instances of `B` also have `A`'s members; we say `B` *inherits* them. - The **`Declared`** methods return only members **physically written in this exact class** — nothing inherited. - The methods **without `Declared`** return members of this class **plus inherited** public members from all superclasses and all implemented interfaces. Put together: | Method | Access levels | Scope | |---|---|---| | `getDeclaredFields()` / `getDeclaredMethods()` / `getDeclaredConstructors()` | ALL (public, protected, package, private) | THIS class only | | `getFields()` / `getMethods()` | public ONLY | this class + inherited (supers + interfaces) | There is intentionally **no** method that returns "all access levels including inherited" in one call — you must do that yourself by walking the hierarchy. ## Constructors are special Constructors are **never inherited** in Java, so there is no `getConstructors()`-includes-parent surprise. `getConstructors()` returns this class's **public** constructors; `getDeclaredConstructors()` returns **all** of this class's constructors regardless of access. Neither ever returns a superclass constructor. ## Walking the hierarchy to get "all inherited" To collect every field a `B` instance carries, including private ones from ancestors, you loop: ``` Class<?> c = B.class; while (c != null) { for (Field f : c.getDeclaredFields()) { ... } c = c.getSuperclass(); // null after Object } ``` `getSuperclass()` returns the parent `Class`, ending at `Object` whose superclass is `null`. ## You still need setAccessible Finding a non-public member with `getDeclared*` does **not** let you read or invoke it. Java's access checks still apply, so you must call `member.setAccessible(true)` first (subject to the module system / `SecurityManager`). Listing and accessing are separate steps. ## Singular lookups mirror the plural ones `getField(name)`/`getMethod(name, paramTypes...)` follow the **public + inherited** rule; `getDeclaredField(name)`/`getDeclaredMethod(name, paramTypes...)` follow the **all-access, this-class-only** rule. The plural and singular forms are consistent. ## Gotchas - `getMethods()` includes `Object`'s public methods (`toString`, `equals`, `hashCode`, …) and all public methods of every implemented interface — the list is often larger than people expect. - The order of the returned array is **not** guaranteed; do not rely on declaration order. - Synthetic / bridge members (compiler-generated, e.g. from generics or nested-class access) appear in `getDeclared*` results; filter with `isSynthetic()` / `isBridge()` if needed.
- How do you get a private field that is declared on a superclass, not the class you start from?Walk up via getSuperclass() in a loop, calling getDeclaredField(name) on each level until you find it (or hit null at Object), then setAccessible(true) to read it.
- Why might getMethods() return far more entries than methods you wrote?It includes all inherited public methods, including Object's (toString/equals/hashCode/...) and every public method of all implemented interfaces.
saying these in an interview costs you the question
- Thinking getDeclaredFields includes inherited fields (it does not)
- Thinking getFields returns private fields (public only)
- Believing getDeclaredMethod lets you invoke a private method without setAccessible
- Expecting getConstructors to return superclass constructors