Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: What is the fastest way to inject fields using reflection?

Suppose, I have a lot of classes, which are constructed using Java reflection (for some reason). Now I need to post-inject values to fields, which are annotated with @PostInject.

public class SomeClass {
  @PostInject
  private final String someString = null;

  public void someMethod() {
    // here, someString has a value.
  }
}

My question is: what is a fast way to set a field using reflection?
Remember, I need to do this very often on a lot of classes, that's why performance is relevant.

What I would do by intuition is shown by this pseudo-code:

  • get all fields of the class
    clazz.getFields();
  • check, which are annotated with @PostInject
    eachField.getAnnotation(PostInject.class);
  • make these fields accessible
    eachAnnotatedField.setAccessible(true);
  • set them to a certain value
    eachAnnotatedField.set(clazz, someValue);

I'm afraid that getting all fields is the slowest thing to do.
Can I someone get a field, when I know it from the beginning?

NOTE: I can't just let the classes implement some interface, which would allow to set the fields using a method. I need POJOs.

NOTE2: Why I want post-field injection: From the point of view of an API user, it must be possible to use final fields. Furthermore, when the types and number of fields are not known by the API a priori, it is impossible to achieve field initialization using an interface.

NOTE2b: From the point of view of the user, the final contract is not broken. It stays final. First, a field gets initialized, then it can't be changed. By the way: there are a lot of APIs which use this concept, one of them is JAXB (part of the JDK).

like image 441
java.is.for.desktop Avatar asked Oct 28 '09 12:10

java.is.for.desktop


1 Answers

How about doing steps 1 to 3 just after you constructed the object and saving the set of annotated fields that you obtain either in the object itself or by keeping a separate map of class to set-of-annotated-fields?

Then, when you need to update the injected fields in an object, retrieve the set from either the object or the seperate map and perform step 4.

like image 163
rsp Avatar answered Sep 29 '22 09:09

rsp