Java 如何使用反射设置基元数组字段?
我正在尝试编写一个函数,它将对象作为参数,并使用其类上的反射从某个二进制文件自动填充它 我已经编写了一些类似于以下内容的代码(简化):Java 如何使用反射设置基元数组字段?,java,parsing,reflection,Java,Parsing,Reflection,我正在尝试编写一个函数,它将对象作为参数,并使用其类上的反射从某个二进制文件自动填充它 我已经编写了一些类似于以下内容的代码(简化): 正确的方法是什么?问题是Vector.toArray()返回Object[]类型的数组,即使它可能包含正确类型的对象-这不是一回事,因此出现了IllegalArgumentException 此外,您永远不能在对象[]和基元类型的数组之间强制转换。相反,您可以使用java.lang.reflect.Array中的实用程序函数,例如newInstance()、se
正确的方法是什么?问题是Vector.toArray()返回Object[]类型的数组,即使它可能包含正确类型的对象-这不是一回事,因此出现了IllegalArgumentException 此外,您永远不能在对象[]和基元类型的数组之间强制转换。相反,您可以使用java.lang.reflect.Array中的实用程序函数,例如newInstance()、set(数组、索引、值)等
使用反射是你唯一的选择吗?反射不是一种快速或健壮的方法当然不是,但是我有很多结构(数百个),我想从二进制读入一个对象,因为我只对查看数据感兴趣,而不关心性能,这似乎是一种方法。你的代码似乎有一些问题。。。e、 g.如果容器变量是在前面的else if中定义的,那么container.toArray()行是如何编译的?也许复制代码时有问题?还有object[]永远不会编译…@ValentinRuano是的,我复制了代码并剪切了不必要的东西。。。我会编辑它,谢谢:)不确定field.set在这里是否有效,例如dummyTypedArray永远不会是短[](可能是短[]),因为短[]不会扩展对象[]。(Object[])可能会失败。更具体地说,它在您的示例中会起作用,但它没有解决问题。这能解决您的问题吗?如果你需要更多的信息,请告诉我
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)
{
//...
}
}
java.lang.IllegalArgumentException: Can not set [B field MyClass.myArrayField to [Ljava.lang.Object;
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);
}
}