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

时间:2018-11-09 07:45:10

标签: java code-generation bytecode byte-buddy

我使用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();

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

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

   // do something special..
}

我尝试使用MethodDelegation.to(DefaultConstructorInterceptor.class)实施工具,但没有成功。

1 个答案:

答案 0 :(得分:1)

JVM要求您将超级方法调用硬编码为方法,这是使用委托无法实现的(另请参见javadoc),这就是为什么您不能使用MethodDelegation来调用构造函数的原因。您可以做的是通过andThen步骤使用合成将您已经拥有的方法调用和委托链接起来,如下所示:

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