【问题标题】:Setting values to object dynamically (dynamic property/type)动态设置对象的值(动态属性/类型)
【发布时间】:2013-02-19 22:34:04
【问题描述】:

我正在尝试创建 JSON 到对象映射器。它的主要思想是“用户”定义了一个字典,其中键是 JSON 属性,值是对象属性名称。那么它是如何工作的(到目前为止):

  1. 从 JSON 中获取值 (var jsonValue)
  2. 从 getter (var methodType) 获取属性类型
  3. 创建setter方法并从json插入值

唯一的问题是我不能动态地将 jsonValue 转换为对象。我必须检查对象类型(methodType)是什么,然后将其转换为 String、Long、Integer 等。我可以以某种方式动态投射它吗?

    private Cookbook createCookbook(JsonObject jsonCookbook) {
    //Cookbook to return
    Cookbook cookbook = new Cookbook();

    Enumeration<String> e = mappingDictionary.keys();
    while (e.hasMoreElements()) {
        //get JSON value
        String mappingKey = e.nextElement();
        JsonElement json = jsonCookbook.get(mappingKey);
        String jsonValue = json.getAsString();

        //set JSON value to property
        String mappingValue = mappingDictionary.get(mappingKey);

        //reflection
        try {
            //get type of the getter
            String getMethodName = "get" + mappingValue; 
            Method getMethod = cookbook.getClass().getMethod(getMethodName, null);
            Class<?> methodType = getMethod.getReturnType(); 

            //set methods
            String setMethodName = "set" + mappingValue;
            Method setMethod = cookbook.getClass().getMethod(setMethodName, methodType);

            //set value to property
            /* DONT WANT TO DO IT LIKE THIS, THIS IS MY PROBLEM */
            if (methodType.equals(String.class))
                setMethod.invoke(cookbook, jsonValue);
            if (methodType.equals(Long.class))
                setMethod.invoke(cookbook, Long.valueOf(jsonValue));

        } catch (NoSuchMethodException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (IllegalArgumentException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (IllegalAccessException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (InvocationTargetException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }           
    }

    return cookbook;
    }

【问题讨论】:

    标签: java android reflection dynamic-cast


    【解决方案1】:

    您可以使用反射(如您所用)和 .newInstance() 方法在运行时创建未知类型的非原始对象。

    您不能以这种方式创建原始类型,例如,如果您查看标准的 JDK 序列化实现(ObjectWriter 的 writeObject()),您会看到有 8 种情况的开关。

    【讨论】:

    • 我可以使用 methodType.newInstance(); 创建一个新类;但我不知道如何将我的字符串(jsonValue)转换为新创建的对象。
    • 查看 ObjectInputStream 的来源;方法“private Object readArray”可能包含您问题的答案
    • 我已经检查过 ObjectInputStream 但正如我所见,他们也在检测类型,然后为每种类型单独解析。我想这就是要走的路。我找不到任何“更聪明”方式
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-27
    • 2012-10-23
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多