Search code examples
javabyte-buddy

Generating a class that access a dynamic field (of a parameterized type) at runtime with ByteBuddy


I am working with Java generics and I am trying to avoid Reflection as much as possible. For that, I found that byte-buddy could help me. However, I am wondering whether I can create a class (subclass of an abstract class) using ByteBuddy that allows me to reach out to a specific attribute of a parameterized type without reflection. Such an abstract class would look like this:

public abstract class AbstractClassTest<V extends Serializable, T extends AbstractEntity> {
    
   public boolean test( T entity ) {
       V value = getValue(entity);
       return value != null;
   }

   public abstract V getValue( T entity );
}

And an entity would look like this:

public class ConcreteEntity extends AbstractEntity {

   public String fieldTest;

   public ConcreteEntity(){
       this.fieldTest = "TEST"
   }

   public String getFieldTest(){
       return this.fieldTest;
   }

}

In other words, I want that my created class overrides the getValue() method found on AbstractClassTest. Another constraint is that I don't know what is the concrete AbstractEntity class at runtime, so I cannot refer to concrete types (i.e., I cannot refer explicitly to ConcreteEntity).

On the other side, the parameterized type V and the attribute name (e.g., "fieldTest") are known. That leads me to "tell" ByteBuddy somehow that in the overrode "getValue" method I want to read a given attribute of T.

Is that possible? If not, what other options are available within the scope of ByteBuddy?

I appreciate any help. Thanks!


Solution

  • You can create such a class. Have a look at the DSL and FieldAccessor for creating (overriding) methods that access fields.

    On the other hand, it seems to me that you should rather look at MethodHandles which can access field values as fast as any Java byte code once generated. And I argue that resolving a method handle takes less resources then creating a class.