gpt4 book ai didi

java - 在 Java 中如何使用 Byte Buddy 分配给字段?

转载 作者:塔克拉玛干 更新时间:2023-11-02 07:46:34 28 4
gpt4 key购买 nike

我很难理解 Byte Buddy 的文档.为了帮助我学习 API,我想生成与此 Java 等效的字节代码:

    public final class GeneratedByByteBuddy {
private final int a;
public GeneratedByByteBuddy(final int a) {
this.a = a;
}
}

我很难找到使用 Instrumentation 创建字段分配的正确方法。

最佳答案

您正在创建一个带有自定义字节码的类。为此,您不能使用内置的Instrumentation,但您需要编写自己的工具,为您的构造函数创建特定的字节码。此 Instrumentation 当然可以为 Byte Buddy 实现,但如果您了解生成类的所有细节,最好使用 javac 编译此类。我假设您想了解 API 而这不是您要创建的实际类。

对于您的示例类,您需要实现构造函数的脱糖版本的等价物。构造函数只是 Java 运行时的方法,但它们遵循由 JVM 的验证程序强制执行的特定语义。脱糖构造函数如下所示:

public GeneratedByByteBuddy(int a) {
super();
this.a = a;
return;
}

这个类的 Byte Buddy 实现如下所示:

new ByteBuddy()
.subclass(Object.class, ConstructorStrategy.Default.NO_CONSTRUCTORS)
.name("my.company.GeneratedByByteBuddy")
.defineField("a", int.class, Visibility.PRIVATE, FieldManifestation.FINAL)
.defineConstructor(Arrays.<Class<?>>asList(int.class), Visibility.PUBLIC)
.intercept(new Instrumentation() {
@Override
public InstrumentedType prepare(InstrumentedType instrumentedType) {
return instrumentedType;
}

@Override
public ByteCodeAppender appender(final Target instrumentationTarget) {
return new ByteCodeAppender() {
@Override
public boolean appendsCode() {
return true;
}

@Override
public Size apply(MethodVisitor methodVisitor,
Context instrumentationContext,
MethodDescription instrumentedMethod) {
StackManipulation.Size size = new StackManipulation.Compound(
MethodVariableAccess.REFERENCE.loadFromIndex(0),
MethodInvocation.invoke(new TypeDescription.ForLoadedType(Object.class)
.getDeclaredMethods()
.filter(isConstructor().and(takesArguments(0))).getOnly()),
MethodVariableAccess.REFERENCE.loadFromIndex(0),
MethodVariableAccess.INTEGER.loadFromIndex(1),
FieldAccess.forField(instrumentationTarget.getTypeDescription()
.getDeclaredFields()
.named("a"))
.putter(),
MethodReturn.VOID
).apply(methodVisitor, instrumentationContext);
return new Size(size.getMaximalSize(), instrumentedMethod.getStackSize());
}
};
}
})
.make()
.load(getClass().getClassLoader(), ClassLoadingStrategy.Default.INJECTION);

每个方法实现都由一个Instrumentation 实现,它能够通过添加字段或方法来修改创建的类型。这对你的类(class)来说不是必需的。然后,它发出一个 ByteCodeAppender,用于查询写入字节码指令。

关于java - 在 Java 中如何使用 Byte Buddy 分配给字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24711172/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com