динамически отображать элементы массива в объекты java.reflect.Field - PullRequest
0 голосов
/ 29 марта 2011

Мне нужно написать код, который имитирует наличие определенного пользователем числа полей в классе во время выполнения. Идея заключается в том, чтобы иметь возможность возвращать объекты 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 (но для полей)? Спасибо

1 Ответ

0 голосов
/ 12 апреля 2011

В итоге я использовал Javassist для: - создания во время выполнения нового определения класса, которое наследует мой исходный класс - ввода нужных мне полей в определение нового класса

Я также заменил открытый конструктор на статическийфабричный метод, который создает и возвращает экземпляр нового определения класса.В целом код выглядит так:

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();
}

}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...