我刚开始玩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>
字段,我该如何完成这项任务?
谢谢!
答案 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]);