vendredi 24 septembre 2021

Updating field using reflection from parent class

I have a Parent class that has a method that uses reflection to retrieve and update fields. This method will be called by the child class

package com.torchai.service.common.response;

import java.lang.reflect.Field;

public class TestReflection {
    private String foo;

    public void update() throws IllegalAccessException {
        final Field[] fields = getClass().getDeclaredFields();
        for (final Field f : fields) {
            //   f.setAccessible(true);
            //   final Object value = response.get(f.getName());
            Object value = "new value";
            f.set(this, value);

        }
    }

    public static void main(final String[] args) throws IllegalAccessException {
        final TestReflection t = new TestReflection() {
            private String abc;
        };

        t.update();
    }
}

When the child class (in this case, an anonymous class) calls the method, which is inherited form the parent, the value of this is the child class. Because of that, I thought there would be no problem in retrieving and setting private fields. It turns out that getDeclaredFields() can retrieve private fields, but Field.set() cannot update them, unless I setAccessible to true. Is this correct behavior? Why can't the child class set its own fields? If I can see the field (i.e., I can retrieve the private field) shouldn't I be able to update it?

The exception I get is

java.lang.IllegalAccessException: Class com.torchai.service.common.response.TestReflection can not access a member of class com.torchai.service.common.response.TestReflection$1 with modifiers "private"

Note that it implies that it is the parent class that it trying to access the child class. Why is the parent class being considered the caller?

If I change the main method to eliminate the use of the child class

TestReflection t = new TestReflection();
t.update()

then it works as expected. The class is updating its own fields, so setAccessbile is not necessary





Aucun commentaire:

Enregistrer un commentaire