mercredi 13 février 2019

Modify property of non-null field using relection/annotations

I have this:

package general;

import org.junit.Test;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Field;


@Retention(RetentionPolicy.RUNTIME)
@interface SetTable {
  String table();
}

class Star {
  public String foo = "";
  public String toString(){
    return "<Star> : " + this.foo;
  }
}

class Bar {

  @SetTable(table = "xxx")
  public Star s = new Star();
  public String toString(){
    return "<Bar> : " + this.s.toString();
  }
}

class AnnotationInjector {
  public static void inject(Object instance) {
    Field[] fields = instance.getClass().getDeclaredFields();


    for (Field field : fields) {

      if (field.isAnnotationPresent(SetTable.class)) {

        SetTable set = field.getAnnotation(SetTable.class);
        field.setAccessible(true); // should work on private fields

        try {
          field.set(instance, set.table());  // this is not what I need
          //  ***
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    }
  }
}

public class AnnotationTest {

  @Test
  public void first() {

    var b = new Bar();
    AnnotationInjector.inject(b);
    System.out.println(b.toString());
  }


}

right now the code is trying to set new Bar().s to a String, but that won't work, because new Bar().s needs to be an instance Star. But that's not what I want to do anyway. What I want to do is access s and set this:

new Bar().s.foo = "whatever"

so on the line above designated by ***

I am looking to do something like:

((Star)field).foo = "whatever";

but that's not right. Is it possible to modify a field after it's been assigned?





Aucun commentaire:

Enregistrer un commentaire