如何使用 ByteBuddy 创建默认构造函数?

How to create a default constructor with ByteBuddy?

我使用 ByteBuddy,我有这个代码:

public class A extends B {
    public A(String a) {
        super(a);
    }

    public String getValue() {
        return "HARDCODED VALUE";
    }
}

public abstract class B {
    private final String message;

    protected B(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }
}

我当前的生成代码是:

Constructor<T> declaredConstructor;

try {
    declaredConstructor = A.class.getDeclaredConstructor(String.class);
} catch (NoSuchMethodException e) {
    //fail with exception..
}

new ByteBuddy()
    .subclass(A.class, Default.IMITATE_SUPER_CLASS)
    .name(A.class.getCanonicalName() + "$Generated")
    .defineConstructor(Visibility.PUBLIC)                               
    .intercept(MethodCall.invoke(declaredConstructor).with("message"))                                                                         
    .make()        
    .load(tClass.getClassLoader(),ClassLoadingStrategy.Default.WRAPPER)
    .getLoaded()
    .newInstance();

我想获取 class A 的实例,而且我想在调用 super() 之后在构造函数中执行一些操作,如下所示:

public A(){
   super("message");

   // do something special..
}

我尝试用 MethodDelegation.to(DefaultConstructorInterceptor.class) 实现,但没有成功。

JVM 要求您将 super 方法调用硬编码到方法中,而使用委托是不可能的(另请参阅 javadoc),这就是为什么您不能使用 MethodDelegation 来调用构造函数的原因。你可以做的是通过 andThen 步骤使用组合来链接你已经拥有的方法调用和委托,如:

MethodCall.invoke(declaredConstructor).with("message")
  .andThen(MethodDelegation.to(DefaultConstructorInterceptor.class));