使用 ElementMatchers 调用 super class 中已在 ByteBuddy 中覆盖的方法

Invoking a method in super class that has been overriden in ByteBuddy using ElementMatchers

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

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", boolean.class, Modifier.PUBLIC)
                .withParameter(int.class).intercept(FixedValue.value(false))

                .defineMethod("testMethodSuperWrapper", boolean.class, 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 class 来使 testMethodSuperWrapper 调用父方法但是由于我项目中的原因(循环类型)我需要创建 testMethodSuperWrapper 使用 ElementMatchers 在父 class 中调用 testMethod

问题是当我使用 ElementMatchers 调用父 class 中的方法时,就像在我的代码中一样,我收到此错误:Cannot invoke public boolean Child.testMethod(int) as super method of class Child.

此外,如果我注释 .onSuper() 行并取消注释 .and(ElementMatchers.isDeclaredBy(parentClass)) 我会得到这个错误 class Child does not define exactly one virtual method or constructor for (isMethod() and name(equals(testMethod)) and hasParameter(hasTypes(erasures(containing(is(int))))) and declaredBy(erasure(is(class Parent)))) but contained 0 candidates: []

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

您可以通过匹配方法来覆盖它,而不是像这样定义它:

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

这样,您的覆盖就会起作用。