繁体   English   中英

使用java反射设置数组的值

[英]Setting value of array using java reflection

我使用java反射创建了通用的json解析器,但是有一个我无法解决的错误。

方法(在这个问题的底部),接收我的自定义Model类的子类。 我遍历字段并从json设置值。 如果子类包含某些其他类的数组属性(同样是Model的子类),我创建了小递归来填充这些对象。

例如。

class UserModel extends Model
{
    @JsonResponseParam(Name="userName")
    public String Name;

    @JsonResponseParam(Name="friends")
    public FriendModel[] Friends;
}

最后,UserModel应该填充好友。 (JsonResponseParam是自定义anotation,Name值用作从json获取值的属性)

此方法的结果是IllegalArgumentException,并且它被抛出

field.set(t, values.toArray());

这是方法:

protected <T extends Model> T getModel(T t)
{
    Field[] fields = t.getClass().getFields();

    for (Field field : fields) {
        Annotation an = field.getAnnotation(JsonResponseParam.class);

        if(an != null){
            try 
            {               
                if(field.getType() == boolean.class)                
                    field.setBoolean(t, t.getBool(((JsonResponseParam)an).Name()));

                if(field.getType() == String.class)
                    field.set(t,  t.getString(((JsonResponseParam)an).Name()));

                if(field.getType() == int.class)
                    field.setInt(t,  t.getInt(((JsonResponseParam)an).Name()));

                if(field.getType() == Date.class)
                    field.set(t,  t.getDate(((JsonResponseParam)an).Name()));

                if(field.getType().isArray()){

                    ArrayList<Model> modelArray = t.getModelArray(((JsonResponseParam)an).Name());
                    ArrayList<Model> values = new ArrayList<Model>();

                    for (Model model : modelArray) {

                        Class<? extends Model> arrayType = field.getType().getComponentType().asSubclass(Model.class);
                        Model m = arrayType.newInstance();
                        m.jsonObject = model.jsonObject;
                        model.getModel(m);
                        values.add(m);                      
                    }

                    field.set(t, values.toArray());
                }

            } catch (IllegalArgumentException e) { 
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            }
        }
    }

    return t;
}

我怀疑字段和值之间的类型不一致..

感谢您的时间。

toArray()只返回一个Object[]因此无法将其分配给任何其他数组类型。

你想要的是什么

field.set(t, values.toArray(Array.newInstance(field.getType().getComponentType(), values.size()));

这将创建一个与该字段匹配的类型数组。

请参见Array.newInstance

基本上,模式如下:

// First, create the array
Object myArray = Array.newInstance(field.getType().getComponentType(), arraySize);

// Then, adding value to that array
for (int i = 0; i < arraySize; i++) {
    // value = ....
    Array.set(myArray, i, value);
}

// Finally, set value for that array field
set(data, fieldName, myArray);

set函数取自此stackoverflow问题

public static boolean set(Object object, String fieldName, Object fieldValue) {
    Class<?> clazz = object.getClass();
    while (clazz != null) {
        try {
            Field field = clazz.getDeclaredField(fieldName);
            field.setAccessible(true);
            field.set(object, fieldValue);
            return true;
        } catch (NoSuchFieldException e) {
            clazz = clazz.getSuperclass();
        } catch (Exception e) {
            throw new IllegalStateException(e);
        }
    }
    return false;
}

应用上面的代码,我们有:

if(field.getType().isArray()){
    // ....
    int arraySize = modelArray.size();
    Object values = Array.newInstance(field.getType().getComponentType(), modelArray.size());
    for (int i = 0; i < arraySize; i++) {
        // ......
        Array.set(values, i, m);                     
    }

    field.set(t, values);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM