Can you change a final field using reflection?

Although final fields are intended to remain unchanged after initialization, reflection can sometimes be used to modify them by bypassing normal access restrictions. However, doing so breaks the immutability contract, can interfere with JVM optimizations, and may lead to unpredictable behavior. For this reason, modifying final fields through reflection is strongly discouraged in production code.

Key Points: • Reflection can bypass access controls using setAccessible(true), allowing modification of certain final fields. • Changing a final field may cause inconsistent behavior because the JVM and compiler often assume final values never change. • Modern Java versions impose stronger restrictions on reflective access, making such modifications more difficult and less reliable.

Example: Consider an immutable configuration object with a final field. If that field is altered through reflection, different parts of the application may observe unexpected values, defeating the purpose of immutability.

Code Example:

import java.lang.reflect.Field;

class Employee {

    private final String name =
            "John";
}

public class Main {

    public static void main(String[] args)
            throws Exception {

        Employee employee =
                new Employee();

        Field field =
                Employee.class
                        .getDeclaredField("name");

        field.setAccessible(true);

        field.set(employee, "David");
    }
}

Interview Tip: A concise interview answer is: Yes, a final field can sometimes be modified using reflection by bypassing normal access checks. However, this violates immutability, may conflict with JVM optimizations, and can result in unpredictable behavior, so it should generally be avoided.