I'm new with byteBudd and doing first test to learn about it I got a solution for a "problem" but I would like to improve it. I would like to generate a this code:
public class A {
private String value;
public A(){}
public A(Map<String, Object> p){
this.value=p.get("value");
}
//getter and setter
}
I made it work using MethodDelegation.to and use of reflection with this code
@Test
public void withReflection() throws Exception {
DynamicType.Builder builder = new ByteBuddy()
.subclass(Object.class, ConstructorStrategy.Default.NO_CONSTRUCTORS)
.name("cat.altimiras.dynamic.AAA") //must be same package
.defineField("value", String.class, Visibility.PRIVATE)
.defineMethod("getValue", String.class, Visibility.PUBLIC)
.intercept(FieldAccessor.ofBeanProperty())
.defineMethod("setValue", void.class, Visibility.PUBLIC)
.withParameters(String.class)
.intercept(FieldAccessor.ofBeanProperty())
.defineConstructor(Visibility.PUBLIC)
.intercept(MethodCall.invoke(Object.class.getDeclaredConstructor()))
.defineConstructor(Visibility.PUBLIC)
.withParameter(Map.class)
.intercept(
MethodCall.invoke(Object.class.getDeclaredConstructor())
.andThen(
MethodDelegation.to(
new Object() {
public void assign(@RuntimeType Map<String, Object> value, @This Object o) throws Exception {
Field f = o.getClass().getDeclaredField("value");
f.setAccessible(true);
f.set(o, value.get("value")); // Reflection
}
}
)
)
);
Class cl = builder.make().load(this.getClass().getClassLoader(), ClassLoadingStrategy.Default.INJECTION).getLoaded();
Map<String, String> p = new HashMap<>();
p.put("value", "lala");
Object o = cl.getConstructor(Map.class).newInstance(p);
Assert.assertEquals("lala", o.getClass().getDeclaredMethod("getValue").invoke(o));
This is working but I don't like because : 1 - I would like to avoid the use of reflection 2 - "A" can't not be to a random package "xyzA" for instance
Do you know if this is possible? And how to do it?
Thanks in advance
You are using a method delegation to an anonymous type which is defined as package-private by the Java compiler. If you define a named, public class, you can invoke the delegator from any package.
Also, use the @FieldValue
annotation rather than reflection to access the field in question.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.