如何使用反射设置原始数组字段?

时间:2015-02-18 21:13:45

标签: java parsing reflection

我正在尝试编写一个函数,该函数将对象作为参数,并使用其类的反射从某些二进制文件中自动填充它。

我写了一些看起来像这样的代码(简化):

for (Field f: obj.getClass().getDeclaredFields()) 
{
    try 
    {
        if (f.getType().isPrimitive())
        {
            Object value = getPrimitiveValue(f.getType());
            f.set(obj, value);
        }
        else if (f.getType().isArray())
        {
            Class<?> compType = f.getType().getComponentType();
            Vector<Object> container = new Vector<Object>();    

            for (int i = 0; i < SOME_ARRAY_SIZE; i++)
            {
                Object item = getPrimitiveValue(compType);
                container.add(item);
            }

            Object[] arr = container.toArray();
            f.set(obj, arr); 
        }
    }
    catch (Exception e)
    {
        //...
    }
}

getPrimitiveType根据组件类型从静态字节缓冲区读取基本类型。

向量容器设置正确的值。例如,如果组件类型很短,则它变为short[]数组。

但是,尝试将数组字段f.set(obj, arr)的值设置为f的调用arr会引发异常:

java.lang.IllegalArgumentException: Can not set [B field MyClass.myArrayField to [Ljava.lang.Object;

这样做的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

问题是Vector.toArray()返回一个Object []类型的数组,即使它可能包含正确类型的对象 - 这不是同一个东西,因此IllegalArgumentException。

此外,您永远不能在Object []和基本类型数组之间进行转换。相反,您可以使用java.lang.reflect.Array中的实用程序函数,例如newInstance(),set(数组,索引,值)等。

public class Test {

    private static short[] horses;

    public static void main(String[] args) throws Exception {
        Field field = Test.class.getDeclaredField("horses");

        Object array = Array.newInstance(field.getType().getComponentType(), 3);
        Array.set(array, 0, (short)123);
        Array.set(array, 1, (short)456);
        Array.set(array, 2, (short)789);

        field.set(new Test(), array);
    }
}