【问题标题】:dynamically map array items to java.reflect.Field objects将数组项动态映射到 java.reflect.Field 对象
【发布时间】:2011-07-24 21:12:52
【问题描述】:

我需要编写代码来模拟在运行时在类中具有用户定义数量的可用字段。这个想法是能够将指向那些“动态”字段的 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 的东西(但对于字段)? 谢谢

【问题讨论】:

    标签: java reflection dynamic


    【解决方案1】:

    我最终使用 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();
    }
    

    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-24
      • 1970-01-01
      • 2021-04-18
      • 2020-11-09
      • 2016-05-31
      • 2018-09-22
      • 2021-07-29
      相关资源
      最近更新 更多