[阅读文档和few Github issues证明是特别有用的之后,我了解到,在ByteBuddy术语中,static
字段必须由某种LoadedTypeInitializer
设置为其初始值。
一旦创建LoadedTypeInitializer.ForStaticField
,我就不知道该怎么做。然后,幸运的是,我偶然发现了initializer()
的DynamicType.Builder
方法。这是我的食谱(不起作用):
builder = builder
.initializer(new LoadedTypeInitializer.ForStaticField("$frob", this.frob))
.defineField("$frob",
Frob.class,
Ownership.STATIC,
SyntheticState.SYNTHETIC,
Visibility.PRIVATE,
FieldManifestation.FINAL);
如果在加载类型后通过反射检查此字段的值,则该字段在那里,但它设置为null
。
如果我从此配方中删除FieldManifestation.FINAL
,它将起作用。但理想情况下,我希望我的领域是final
。这可能吗?
默认的初始值设定项需要一个非最终字段,但是您可以自己实现,以通过将setAccessible
调用为true
来设置最终字段的值。
一种更优雅的解决方案可能是在静态初始化器中设置该字段。这种方法的问题是,除非调用初始化程序时可以从某个地方访问该字段,否则只能设置从编译时常量(基元和字符串)汇编的值。例如:
builder = builder.invokeable(isTypeInitializer()).intercept(MethodCall.invoke(...).setsField(...))
您需要创建一个FieldDescription.Latent
来引用您创建的字段。