Java
Private Fields
Class Interaction
Programming How-To
Object-Oriented Programming

How to read the value of a private field from a different class in Java?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

In normal Java code, you are not supposed to read another class’s private field directly. private exists to preserve encapsulation, so the preferred solution is usually a getter, constructor parameter, or another explicit API. If you truly must access the field anyway, reflection is the standard mechanism, but it comes with real tradeoffs and newer Java versions make it more restricted.

Prefer a Real API First

The cleanest solution is to expose the data intentionally.

java
1public class Person {
2    private final String name;
3
4    public Person(String name) {
5        this.name = name;
6    }
7
8    public String getName() {
9        return name;
10    }
11}

Then another class can read it safely:

java
Person person = new Person("Mina");
System.out.println(person.getName());

This preserves the class’s contract and keeps refactoring safer. If you control the class design, this is almost always better than breaking encapsulation.

Use Reflection Only When You Really Need It

If the class is from a third-party library, legacy code, or a test helper scenario, reflection lets you inspect a private field.

java
1import java.lang.reflect.Field;
2
3public class ReflectionExample {
4    public static void main(String[] args) throws Exception {
5        Person person = new Person("Mina");
6
7        Field field = Person.class.getDeclaredField("name");
8        field.setAccessible(true);
9
10        String value = (String) field.get(person);
11        System.out.println(value);
12    }
13}

The important steps are:

  1. get the Field object with getDeclaredField
  2. override access checks with setAccessible(true)
  3. read the value from the target instance

That works for many classic Java use cases, especially in tests and frameworks.

Reading and Writing the Field

Reflection can both read and write private fields.

java
1import java.lang.reflect.Field;
2
3public class ReflectionWriteExample {
4    public static void main(String[] args) throws Exception {
5        Person person = new Person("Mina");
6
7        Field field = Person.class.getDeclaredField("name");
8        field.setAccessible(true);
9
10        System.out.println(field.get(person));
11        field.set(person, "Noah");
12        System.out.println(field.get(person));
13    }
14}

This power is exactly why reflection should be used carefully. It bypasses the class’s intended invariants.

Modern Java Restrictions

On Java 9 and later, the module system can block reflective access even if you call setAccessible(true). In strongly encapsulated environments, you may see InaccessibleObjectException.

That usually means one of these is true:

  • the target package is not opened to your module
  • you are accessing JDK internals
  • the runtime blocks deep reflection for security or configuration reasons

In module-based applications, you may need opens in module-info.java or a JVM flag such as --add-opens. That is one reason reflection-heavy code has become more fragile on newer Java versions.

Good Use Cases for Reflection

Reflection is most defensible when:

  • writing a testing utility
  • integrating with a serialization or mapping framework
  • inspecting third-party objects for diagnostics
  • maintaining legacy code you cannot redesign yet

It is much less convincing when used as a shortcut inside ordinary business logic. If application code constantly needs to reach into another object’s private state, the design usually wants a better interface.

Common Pitfalls

The first mistake is using reflection when a getter would solve the problem more cleanly. That adds complexity for no real gain.

Another common problem is forgetting the field name must match exactly, including case. getDeclaredField("Name") and getDeclaredField("name") are not the same.

Type handling is also easy to get wrong. Field.get() returns Object, so you usually need a cast unless you are using primitive-specific accessors such as getInt().

Finally, do not assume reflective access will keep working forever across Java versions or module boundaries. If your code depends on it, test it on the exact runtime you deploy.

Summary

  • The preferred way to read private data is an explicit API such as a getter.
  • Reflection can access a private field with getDeclaredField and setAccessible(true).
  • Reflection should be reserved for tests, frameworks, diagnostics, or legacy integration.
  • On newer Java versions, module boundaries can block deep reflective access.
  • If ordinary application logic needs private-field access, the design probably needs a better public contract.

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions