2017-09-29 14 views
3

フィールドをスーパークラスへの呼び出しでコンストラクタを定義して初期化:私は(Sampleクラスから阻害する動的なクラスを作成し、それにフィールドを追加したいバイトバディ - のような私は、クラスを持っている

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) 

私は何間違っている?あなたは、コンストラクタの定義でそれを使用し始める前に、フィールドcを定義しない

public class SampleSon extends Sample { 
    private String c; 
    public SampleSon(String a, String b, String c) { 
     super(a,b); 
     this.c = c; 
    } 

    public String getC() { return c;} 
} 
+0

回答に記載されているとおり:Byte Buddyは完全に変更できません。ライブラリ内の呼び出しを連鎖させる必要があります。 –

答えて

2

: は、私はそのようなことをするクラスを作成します。

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に応じて呼び出します。

+0

フィールドを作成しています: classBuilder.defineField( "c"、String.class、Visibility.PRIVATE); さらに簡単なコンストラクタを作成しようとしましたが、失敗しました:classBuilder.defineConstructor(Visibility.PUBLIC).withParameters(String.class、String.class)。 インターセプト(MethodCall.invoke(Sample.class.getConstructor(String.class、String.class)).Argument(0,1)); –

+0

@Rotemben 'ByteBuddy'のjavadocによれば、すべてのメソッド呼び出しは、私の例のように連鎖されなければなりません。 –

+0

@ Luciano van der Veekensは働いてくれました:)ありがとうございました!!! –

関連する問題