【问题标题】:How to set a primitive array field using reflection?如何使用反射设置原始数组字段?
【发布时间】:2015-02-18 21:13:44
【问题描述】:

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

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

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 的值设置为 arr 的调用 f.set(obj, arr) 会引发异常:

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

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

【问题讨论】:

  • 使用反射是您唯一的选择吗?反思不是一种快速或稳健的做事方式
  • 嗯,当然不是,但是我有很多结构(数百个)我想从二进制文件中读取到一个对象中,因为我只对查看数据感兴趣而不关心关于性能,这似乎是这样做的方法
  • 您的代码似乎有一些问题...例如如果在前面的 else-if 中定义了容器变量,那么 container.toArray() 行如何编译?可能是复制代码有问题?
  • 同样 object[] 永远不会编译....
  • @ValentinRuano 是的,我复制了代码并剪掉了不必要的东西......我会编辑它,谢谢 :)

标签: java parsing reflection


【解决方案1】:

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

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

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

【讨论】:

  • 不确定 field.set 是否可以在这里工作,例如dummyTypedArray 永远不会是 short[](可能是 Short[]),因为 short[] 不会扩展 Object[]。 (Object[]) 可能会失败。
  • 更具体地说,它适用于您的示例,但不能解决问题。
  • 这能解决您的问题吗?如果您需要更多信息,请告诉我
猜你喜欢
  • 1970-01-01
  • 2014-07-28
  • 2016-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多