[英]Create a class constructor from scratch in ByteBuddy
我正在嘗試使用ByteBuddy從頭開始創建Java類。 一個類應該有一堆私有的final屬性和一個構造函數,它們使用傳遞的參數初始化它們。 我開始時:
DynamicType.Builder<?> builder = new ByteBuddy()
.subclass(Object.class)
.implement(Serializable.class)
.modifiers(Visibility.PUBLIC, TypeManifestation.FINAL)
.name("Structure");
// for each property to be declared
builder = builder.defineField(bindingName, bindingType, visibility.PRIVATE, FieldManifestation.FINAL);
// end of for
builder = builder.defineConstructor(Visibility.PUBLIC)
.withParameters(bindings)
.intercept(/* Some implementation is supposed to go here*/);
我有幾個問題:
ByteBuddy是否為開箱即用提供了一些合適的實現?
是否存在開箱即用的ByteBuddy實現類概述?
如果沒有這樣的實現開箱即用,我會感謝你提供一些關於如何使我自己的實現實例服務於我的目的的提示。
沒有找到任何准備好的實現,所以最終寫我自己的。 它尚未最終確定,但它確實有效。 這里是:
final class ConstructorImplementation implements Implementation {
static private final class BCA implements ByteCodeAppender {
@Override
public Size apply(MethodVisitor methodVisitor, Context implementationContext, MethodDescription instrumentedMethod) {
TypeDescription instrumentedType = implementationContext.getInstrumentedType();
Iterator<? extends ParameterDescription> iterator = instrumentedMethod.getParameters().iterator();
List<StackManipulation> insr = new ArrayList<>();
insr.add(MethodVariableAccess.loadThis());
insr.add(MethodInvocation.invoke(TypeDescription.OBJECT.getDeclaredMethods().get(0)));
for (FieldDescription.InDefinedShape field : instrumentedType.getDeclaredFields()) {
ParameterDescription.InDefinedShape param = iterator.next().asDefined();
insr.add(MethodVariableAccess.loadThis());
insr.add(MethodVariableAccess.load(param));
insr.add(FieldAccess.forField(field).write());
}
insr.add(MethodReturn.VOID);
StackManipulation.Size operandStackSize = new StackManipulation.Compound(
insr
).apply(methodVisitor, implementationContext);
return new Size(operandStackSize.getMaximalSize(),
instrumentedMethod.getStackSize());
}
}
private final BCA bca;
public ConstructorImplementation() {
bca = new BCA();
}
@Override
public ByteCodeAppender appender(Target implementationTarget) {
return bca;
}
@Override
public InstrumentedType prepare(InstrumentedType instrumentedType) {
return instrumentedType;
}
}
我會暫時擱置這個問題,因為有人知道更好的解決方案。
您可以通過MethodCall
和FieldAccessor
的組合MethodCall
實現這樣的構造FieldAccessor
:
DynamicType.Builder<?> builder = ...;
Implementation interceptor = StubMethod.INSTANCE;
// for each field
builder = builder.defineField(bindingName,
bindingType, visibility.PRIVATE, FieldManifestation.FINAL);
interceptor = FieldAccessor.ofField(bindingName)
.setsArgumentAt( ... )
.andThen(interceptor);
interceptor = MethodCall.invoke( ... ).andThen(interceptor);
方法調用必須調用已檢測類或超類構造函數的特定構造函數(可能是Object
的默認構造函數)。 參數索引必須是分配給該字段的參數的索引(從零開始)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.