Byte Buddy - 定义构造函数,调用超类并初始化字段

时间:2017-09-29 08:07:26

标签: java byte-buddy dynamic-class-creation dynamic-class

我有一个类如:

       KioskConfirm.include({
                       init : function (){
                              this._super.applay(this, arguments)
                               //.your code here 
                      }
         });

我想创建一个动态类,它将从Sample类继承,并向其添加字段(String字段)。

我试着这样做:

public class Sample{

private String a;
private String b;

public Sample(String a, String b)
{
    this.a = a;
    this.b = b;
}
 public String getA() {return a;}
 public String getB() {return b;}
}

但是当我尝试从这个类创建一个实例时:

DynamicType.Builder<? extends Sample> classBuilder = new ByteBuddy()
        .subclass(Sample.class, ConstructorStrategy.Default.NO_CONSTRUCTORS)
        .name("sampleSon");

classBuilder.defineConstructor(Visibility.PUBLIC)
        .withParameters(String.class, String.class, String.class)
        .intercept(MethodCall.invoke(Sample.class.getConstructor(String.class, String.class))
                .withArgument(0, 1)
                .andThen(FieldAccessor.ofField("c").setsArgumentAt(2)));

它引发了异常:

Class<? extends Sample> newSampleClass= classBuilder.make().load(ClassLoader.getSystemClassLoader()).getLoaded();
Sample sample = newSampleClass.getConstructor(String.class, String.class, String.class).newInstance("a", "b", "c");

我做错了什么? 我想创建一个类:

java.lang.NoSuchMethodException: sampleSon.<init>(java.lang.String, java.lang.String, java.lang.String)

1 个答案:

答案 0 :(得分:2)

在开始在构造函数定义中使用字段c之前,不要定义它。

Class<? extends Sample> clazz = new ByteBuddy()
        .subclass(Sample.class, ConstructorStrategy.Default.NO_CONSTRUCTORS)
        .name("SampleSon")
        .defineField("c", String.class, Visibility.PRIVATE)
        .defineConstructor(Visibility.PUBLIC)
        .withParameters(String.class, String.class, String.class)
        .intercept(MethodCall.invoke(Sample.class.getConstructor(String.class, String.class))
                .withArgument(0, 1)
                .andThen(FieldAccessor.ofField("c").setsArgumentAt(2)))
        .make()
        .load(ClassLoader.getSystemClassLoader())
        .getLoaded();

注意:您还需要根据ByteBuddy的javadoc链接所有方法调用。