1

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

问题是当我使用 ElementMatchers 调用父类中的方法时,就像在我的代码中一样,我收到此错误: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: []

4

1 回答 1

1

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

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

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

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

于 2021-07-02T19:28:58.020 回答