Define field with generic type using ByteBuddy

久未见 提交于 2020-08-04 20:07:32

问题


I just started playing with ByteBuddy and I am working on a couple examples in order to get the hang of it.

What I am trying to accomplish with this exercise is to replace some code that uses ASM, with ByteBuddy.

So far I have been successful when it comes to non-generic types. For example I can easily define a field for example like this

builder.defineField("names", List.class, Visibility.PRIVATE)

if all I want to do is create a field of raw List type.

When it comes to introducing generics however, I am stuck.

Obviously the way I have defined the field (using a Class) means that the generic types are lost. Reading the documentation (especially the Working with generic types part), I can't really figure out how I would construct a List field if it has a known generic type, like for example if it's another POJO. Let's say I have the following POJO:

public class Dummy {
   private String name;

   //getters, setters
}

and I want to create a field of List<Dummy>, how would I accomplish such a task?

Thanks!


回答1:


Instead of providing a Class<List> to the defineField method, you can provide a Type. ByteBuddy has a helper class to create generic Types so you don't need to create an implementation yourself. I put it on a separate line to make it more visible.

    // Create List<Dummy> as Type
    Generic generic = TypeDescription.Generic.Builder
            .parameterizedType(List.class, Dummy.class).build();

    Class<? extends Example> loaded = new ByteBuddy().subclass(Example.class)
            .defineField("names", generic, Visibility.PRIVATE).make()
            .load(ByteBuddyEnhancer.class.getClassLoader(), ClassLoadingStrategy.Default.INJECTION).getLoaded();

One way of validating the field is actually set and contains the generic parameters would be this testcase

    Field field = loaded.getDeclaredField("names");
    Type fieldType = field.getGenericType();
    Assert.assertTrue(fieldType instanceof ParameterizedType);
    ParameterizedType genericFieldType = (ParameterizedType)fieldType;
    Assert.assertEquals(Dummy.class, genericFieldType.getActualTypeArguments()[0]);
    System.out.println(genericFieldType.getRawType());
    System.out.println(genericFieldType.getActualTypeArguments()[0]);


来源:https://stackoverflow.com/questions/45864313/define-field-with-generic-type-using-bytebuddy

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!