Set private field value with reflection

To access a private field you need to set Field::setAccessible to true. You can pull the field off the super class. This code works:

Class<?> clazz = Child.class;
Object cc = clazz.newInstance();

Field f1 = cc.getClass().getSuperclass().getDeclaredField("a_field");
f1.setAccessible(true);
f1.set(cc, "reflecting on life");
String str1 = (String) f1.get(cc);
System.out.println("field: " + str1);

Using FieldUtils from the Apache Commons Lang 3:

FieldUtils.writeField(childInstance, "a_field", "Hello", true);

The true forces it to set, even if the field is private.


Kotlin verison

Get private variable using below extension functions

fun <T : Any> T.getPrivateProperty(variableName: String): Any? {
    return javaClass.getDeclaredField(variableName).let { field ->
        field.isAccessible = true
        return@let field.get(this)
    }
}

Set private variable value get the variable

fun <T : Any> T.setAndReturnPrivateProperty(variableName: String, data: Any): Any? {
    return javaClass.getDeclaredField(variableName).let { field ->
        field.isAccessible = true
        field.set(this, data)
        return@let field.get(this)
    }
}

Get variable use:

val bool = <your_class_object>.getPrivateProperty("your_variable") as String

Set and get variable use:

val bool = <your_class_object>.setAndReturnPrivateProperty("your_variable", true) as Boolean
val str = <your_class_object>.setAndReturnPrivateProperty("your_variable", "Hello") as String

Java version

public class RefUtil {

    public static Field setFieldValue(Object object, String fieldName, Object valueTobeSet) throws NoSuchFieldException, IllegalAccessException {
        Field field = getField(object.getClass(), fieldName);
        field.setAccessible(true);
        field.set(object, valueTobeSet);
        return field;
    }

    public static Object getPrivateFieldValue(Object object, String fieldName) throws NoSuchFieldException, IllegalAccessException {
        Field field = getField(object.getClass(), fieldName);
        field.setAccessible(true);
        return field.get(object);
    }

    private static Field getField(Class mClass, String fieldName) throws NoSuchFieldException {
        try {
            return mClass.getDeclaredField(fieldName);
        } catch (NoSuchFieldException e) {
            Class superClass = mClass.getSuperclass();
            if (superClass == null) {
                throw e;
            } else {
                return getField(superClass, fieldName);
            }
        }
    }
}

Set private value use

RefUtil.setFieldValue(<your_class_object>, "your_variableName", newValue);

Get private value use

Object value = RefUtil.getPrivateFieldValue(<your_class_object>, "your_variableName");

This one can access private fields as well without having to do anything

import org.apache.commons.lang3.reflect.FieldUtils;
Object value = FieldUtils.readField(entity, fieldName, true);

You can use Manifold's @Jailbreak for direct, type-safe Java reflection:

@Jailbreak Child child = new Child();
child.a_field = "123;

@Jailbreak unlocks the child local variable in the compiler for direct access to all the members in Child's hierarchy.

Similarly you can use the jailbreak() extension method for one-off use:

child.jailbreak().a_field = "123";

Through the jailbreak() method you can access any member in Child's hierarchy.

In both cases the compiler resolves the field access for you type-safely, as if a public field, while Manifold generates efficient reflection code for you under the hood.

Discover more about Manifold.