我正在尝试编写一个函数,该函数将对象作为参数,并使用其类的反射从某些二进制文件中自动填充它。
我写了一些看起来像这样的代码(简化):
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;
这样做的正确方法是什么?
答案 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);
}
}