使用ByteBuddy定义具有泛型类型的字段

时间:2017-08-24 14:30:53

标签: java byte-buddy

我刚开始玩ByteBuddy,我正在研究几个例子,以便掌握它。

我想用这个练习来完成的是用ByteBuddy替换一些使用ASM的代码。

到目前为止,我在非泛型类型方面取得了成功。例如,我可以轻松定义一个字段,例如像

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

如果我想要做的就是创建一个原始List类型的字段。

然而,当谈到引入泛型时,我陷入困境。

显然我定义字段的方式(使用Class)意味着泛型类型丢失了。阅读documentation(特别是Working with generic types部分),如果它有一个已知的泛型类型,我就无法弄清楚如何构建一个List字段,例如,如果它是'另一个POJO。让我们说我有以下POJO:

public class Dummy {
   private String name;

   //getters, setters
}

我想创建一个List<Dummy>字段,我该如何完成这项任务?

谢谢!

1 个答案:

答案 0 :(得分:2)

您可以提供Class<List>,而不是向defineField方法提供Type。 ByteBuddy有一个辅助类来创建泛型类型,因此您不需要自己创建实现。我把它放在一个单独的行上,使其更加明显。

    // 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();

实际设置了验证字段的一种方法,并且包含通用参数将是此测试用例

    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]);