使用 ElementMatchers 调用已在 ByteBuddy 中覆盖的超类中的方法

问题描述

我想在bytebuddy中动态创建这样的类

public class Parent {

    public boolean testMethod(int n){
        return true;
    }
}

public class Child extends Parent{

    @Override
    public boolean testMethod(int n) {
        return false;
    }

    public boolean testMethodSuperWrapper(int n){
        return super.testMethod(n);
    }
}

我写的代码是这样的:

Class parentClass = new ByteBuddy().subclass(Object.class).name("Parent")

                .defineMethod("testMethod",boolean.class,Modifier.PUBLIC)
                .withParameter(int.class).intercept(FixedValue.value(true))

                .make().load(Test.class.getClassLoader()).getLoaded();

Class childClass = new ByteBuddy().subclass(parentClass).name("Child")

                .defineMethod("testMethod",Modifier.PUBLIC)
                .withParameter(int.class).intercept(FixedValue.value(false))

                .defineMethod("testMethodSuperWrapper",Modifier.PUBLIC)
                .withParameters(int.class).intercept(MethodCall.invoke(
                        ElementMatchers.isMethod()
                                .and(ElementMatchers.hasMethodName("testMethod"))
                                .and(ElementMatchers.takesArguments(int.class))
                        //.and(ElementMatchers.isDeclaredBy(parentClass))
                )
                        .onsuper()
                        .withAllArguments())
                .make().load(parentClass.getClassLoader()).getLoaded();


        Object childClassObject = childClass.newInstance();
        Method superWrapperMethod = childClass.getmethod("testMethodSuperWrapper",int.class);
        boolean res = (boolean) superWrapperMethod.invoke(childClassObject,23);
        System.out.println(res);

我知道我可以使用 Method 类来使 testMethodSuperWrapper 调用方法,但由于我的项目(循环类型)中的原因,我需要创建 testMethodSuperWrapper 调用 {{1 }} 在父类中使用 ElementMatchers。

问题是当我使用 ElementMatchers 调用父类中的方法时,就像在我的代码中一样,我收到此错误testMethod

此外,如果我注释 Cannot invoke public boolean Child.testMethod(int) as super method of class Child 行并取消注释 .onsuper(),我将收到此错误 .and(ElementMatchers.isDeclaredBy(parentClass))

解决方法

这与 Byte Buddy 的内部模型有关,在该模型中,您替换由超类型定义的方法,而不是覆盖它。在 Java 中这确实是一样的,但在 Byte Buddy 中,它(不幸的是)不是。

您可以通过匹配来覆盖一个方法,而不是将其定义为:

new ByteBuddy().subclass(parentClass).name("Child")              
  .method(ElementMatchers.named("testMethod"))
  .intercept(FixedValue.value(false))

这样,您的覆盖将起作用。