问题
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