我刚开始与ByteBuddy一起玩,并且正在研究几个示例,以便掌握它。
我试图通过此练习完成的工作是用ByteBuddy替换一些使用ASM的代码。
到目前为止,当涉及到非泛型类型时,我已经取得了成功。例如,我可以轻松地定义一个像这样的字段
builder.defineField("names", List.class, Visibility.PRIVATE)
Run Code Online (Sandbox Code Playgroud)
如果我只想创建一个原始List类型的字段。
但是,在介绍泛型时,我很困惑。
显然,我定义字段的方式(使用Class)意味着通用类型会丢失。阅读文档(尤其是该Working with generic types部分)后,我无法真正弄清楚如果List字段具有已知的通用类型(例如,如果它是另一个POJO)如何构造List字段。假设我有以下POJO:
public class Dummy {
private String name;
//getters, setters
}
Run Code Online (Sandbox Code Playgroud)
并且我想创建一个的字段List<Dummy>,我将如何完成这样的任务?
谢谢!
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();
Run Code Online (Sandbox Code Playgroud)
实际设置验证字段的一种方法,它包含通用参数就是该测试用例
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]);
Run Code Online (Sandbox Code Playgroud)