Как получить закрытые поля и вызвать частные методы в методе, завернутом в рекомендации?

#byte-buddy

Вопрос:

Переопределить метод:

   private <T> void redefine(Class<T> type, UnaryOperator<DynamicType.Builder<T>> operation) {
    DynamicType.Builder<T> builder = new ByteBuddy().redefine(type);
    ClassLoader systemClassLoader = Entity.class.getClassLoader();

    operation
            .apply(builder)
            .make()
            .load(systemClassLoader, ClassReloadingStrategy.fromInstalledAgent());
}
 

Использование советов:

         redefine(ChunkGeneratorAbstract.class, builder -> builder
            .method(named("buildNoise")
                    .and(takesArguments(3)))
            .intercept(Advice.to(ChunkGeneratorAdvice.class).wrap(StubMethod.INSTANCE)));
 

ChunkGeneratorAdvice:

  @Advice.OnMethodExit
public static void buildNoise(GeneratorAccess generatoraccess, StructureManager structuremanager, IChunkAccess ichunkaccess,
                              @Advice.This ChunkGeneratorAbstract chunkGenerator) {

    int val = chunkGenerator.n;
    Object someVal = chunkGenerator.privateMethod();
}
 

chunkGenerator.n-это частное поле. Как получить его ценность?

Кроме того, как я могу вызывать частные методы, такие как chunkGenerator.privateMethod()?

Ответ №1:

Для частного поля вы можете использовать Advice.FieldValue его в качестве аннотации к параметру для чтения и записи из него. Для вызова метода вам нужно будет использовать a MemberSubstitution . Затем вы объявите пустой метод в классе рекомендаций, который имеет ту же подпись, и вызовете этот метод из своего кода рекомендаций. Позже вы будете использовать MemberSubstitution для переключения вызовов методов.