2017-09-29 11 views
3

를 초기화 : 나는 샘플 클래스에서 억제하고, (여기에 필드를 추가하는 동적 클래스를 만들바이트 버디 - 슈퍼 클래스 호출 생성자를 정의하고 내가 같은 클래스가 필드를

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). intercept (MethodCall.invoke (Sample.class.getConstructor (String.class, String.class)) .Argument (0,1))와 함께 사용합니다. –

+0

@Rotemben'ByteBuddy'의 javadoc에 따르면, 모든 메소드 호출은 내 예제처럼 체인되어야합니다. –

+0

@ Luciano van der Veekens는 일했습니다 :) 고마워요 !!! –