我是byteBudd的新手,正在做第一个测试以了解它,我为“问题”找到了解决方案,但我想改进它。我想生成一个这段代码:
public class A {
private String value;
public A(){}
public A(Map<String, Object> p){
this.value=p.get("value");
}
//getter and setter
}
我使用MethodDelegation.to使其工作并通过此代码使用反射
@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));
这正在工作,但我不喜欢,因为:1-我想避免使用反射2-例如,“ A”不能不是随机包“ x.y.z.A”
您知道是否可行?以及如何做?
提前感谢
您正在使用方法委托给匿名类型,该类型由Java编译器定义为程序包专用。如果定义了一个命名的公共类,则可以从任何包中调用委托者。
此外,请使用@FieldValue
批注而不是反射来访问相关字段。