改变方法的可见性

Changing the visibility of a method

是否可以(只)改变 Byte Buddy 某些方法的可见性?我有一个使用私有静态方法的用户 class,我需要委托对这些方法的一些调用,但它目前失败了,因为它们是私有的。所以,我想知道我是否可以通过添加 public 修饰符来转换上述方法来重新定义用户 class。

郑重声明,在目标 Java 方法上调用 setAccessible(true) 方法无效,因为 Byte Buddy 仍然失败并出现以下异常:

java.lang.IllegalStateException: class net.bytebuddy.renamed.java.lang.Object$ByteBuddy$VHdvjIkb cannot see private java.lang.String org.mockaccino.MockaccinoTest.lambda() throws java.lang.Exception
at net.bytebuddy.implementation.MethodCall$MethodInvoker$ForContextualInvocation.invoke(MethodCall.java:2387)
...

我发现了一些可以解决问题的 API,但我需要检测这些方法,而我的情况不需要。

例如:

byteBuddy.redefine(targetClass)
  .method(ElementMatchers.named(targetMethod.getName()))
  .intercept(???)
  .transform(Transformer.ForMethod.withModifiers(Visibility.PUBLIC))
  .make()
  .load(getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());

我的问题是:是否有拦截器能够调用正在重新定义的源方法的主体?

或者是否有其他方法可以使目标方法public可见?

重新定义方法的修饰符不适用于已加载的 class。 JVM 拒绝任何 add/remove 方法或更改任何方法属性的重新定义,例如它的修饰符。

为了制作方法 public,您需要应用变基而不是重新定义,在其中您通过 SuperMethodCall.INSTANCE 检测方法。需要在首次加载相关 class 之前应用此转换。