2011-03-28 9 views
0

런타임에 클래스에서 사용할 수있는 사용자 정의 개수의 필드를 시뮬레이트하는 코드를 작성해야합니다. 이 "동적"필드를 가리키는 java.reflect.Field 객체를 클라이언트 코드로 반환 할 수있는 아이디어.배열 항목을 java.reflect.Field 객체에 동적으로 매핑하십시오.

class DynamicFieldClass { 
/** 
    * fieldNames is the list of names of the fields we want to "exist" in the class 
    * they will all be of the same type (say String) 
    */ 
public DynamicFieldClass(List<String> fieldNames) { 
// ... what do we do here 
} 
public Field getFieldObjectFor(String desiredFieldName) { 
// ... what do we do here 
} 
} 

DynamicProxy와 비슷한가요? 감사

답변

0
I가와 Javassist를 사용하여 종료

: - 나는 또한 public 생성자를 대체

나는 새로운 클래스 정의에 필요한 필드를 주입 ​​- 내 원래 클래스 에서 상속 런타임에 새로운 클래스 정의를 작성 새 클래스 정의의 인스턴스를 만들고 반환하는 정적 팩터 리 메서드에 의해 호출됩니다. 모두 모두, 코드는 다음과 같습니다

class DynamicFieldClass { 
protected DynamicFieldClass() { 
}  
public Field getFieldObjectFor(String desiredFieldName) { 
    return null; 
} 

/** 
* fieldNames is the list of names of the fields we want to "exist" in the class 
* they will all be of the same type (say String) 
*/ 
public static createInstance (List<String> fieldNames) { 
    ClassPool defaultClassPool = ClassPool.getDefault(); 
    CtClass originalClass = defaultClassPool.get("DynamicFieldClass"); 
    CtClass newClass = defaultClassPool.makeClass("modified_DynamicFieldClass", originalClass); 

    StringBuilder getterCore = new StringBuilder();   
    for (String item : fieldNames) { 
     CtField addedField = CtField.make(String.format("private String %s;", item), newClass); 
     newClass.addField(addedField); 
     getterCore.append(String.format("if \"%s\".equals(%1) { return this.class.getDeclaredField(%s);}", item, item)); 
    }    
    getterCore.append("throw new IllegalArgumentException(\"Unknown field name: \" + $1);"); 
    final String sourceGeneralGetter = String.format("{%s}", getterCore.toString()); 
    CtMethod mold = originalClass.getDeclaredMethod("getFieldObjectFor"); 
    CtMethod copiedMeth = CtNewMethod.copy(mold, newClass, null); 
    newClass.addMethod(copiedMeth); 
    CtMethod getMeth = newClass.getDeclaredMethod("getFieldObjectFor"); 
    getMeth.setBody(sourceGeneralGetter); 
    CtConstructor defaultCtor = new CtConstructor(new CtClass[0], newClass); 
    defaultCtor.setBody("{}"); 
    newClass.addConstructor(defaultCtor); 
    Class modifiedClass = newClass.toClass(); 
    return modifiedClass.newInstance(); 
} 

}

관련 문제