Sometimes, after many attempts, you realized that to complete your mission, you must access private fields, or perhaps change final fields.

There are many reasons imaginable: the accessors copy the entire object before returning, and that takes a very long time, the authors forgot to provide an accessor, the library function is highly inefficient and you need to do better, …

Are you out of luck? Fortunately, no.

Consider this class:

class A {
    private final Integer value;
    private static final Integer staticValue = 1;

    public A(int value) {
        this.value = value;
    }

    public void print() {
        System.out.println(value);
    }

    public static void printStatic() {
        System.out.println(staticValue);
    }
}

This will be our test. It has two private and final fields, and one of them is static.

Note that this class reflects a common pain: you can access the data without messing with the private field, but not in a thread-safe way: you can replace System.out for the duration of A.print, but that would mess with any other thread trying to print.

Fortunately, we have a better way: through reflection.

To get started, first add import java.lang.reflect.*; to your file. What you can achieve is best illustrated with an example:

A a = new A(1);
// a.value is not accessible.
a.print(); // prints 1

// Access a.value.
Field value = a.getClass().getDeclaredField("value");
value.setAccessible(true); // make the private field accessible
System.out.println(value.get(a)); // prints 1, but we accessed a private field.

// Final instance fields can be changed.
value.set(a, 2);
a.print(); // prints 2

We can do something similar for the private static final field:

Field staticValue = A.class.getDeclaredField("staticValue");
staticValue.setAccessible(true);
// use null to access static fields.
System.out.println(staticValue.get(null)); // prints 1

// This throws IllegalAccessException because Java doesn't like it when you change final fields.
staticValue.set(null, 2);

Fortunately, we are not exactly out of luck. We can use reflection to modify the Field object:

Field modifiers = Field.class.getDeclaredField("modifiers");
modifiers.setAccessible(true);
modifiers.setInt(staticValue, modifiers.getInt(staticValue) & ~Modifier.FINAL);

This takes the Modifier.FINAL bit off the modifiers bit field. Now we can proceed:

staticValue.set(null, 2);
a.printStatic(); // prints 2

A word of caution: if a static final field is a primitive type like int, boolean, etc., then the compiler could inline the field value directly. You can still change the field, but anywhere where the field is inlined, the change will not be reflected. This may lead to all sorts of strange behaviours. Hence, we used Integer objects in the examples.

In conclusion, tread carefully when messing with private or final fields. Doing so can bring new possibilities to your program, but not all possibilities are good. Looking at it from the other side though: do not count on private fields to provide “security”.

Most importantly, do not count your program working with the next version of whatever class you are messing with. private fields are obviously not part of the public interface and can change any time. It is now your responsibility to make sure this doesn’t become an issue.