Java反射和自动装箱

Java反射和自动装箱,java,reflection,autoboxing,Java,Reflection,Autoboxing,我使用反射来设置字段值,但当我尝试将Short指定给Short时,会出现错误,因为isAssignable()返回false private void setFieldValue(Object result, Field curField, Object value) throws NoSuchFieldException, IllegalAccessException { if (!curField.getType().isAssignableFrom(value.getClass()

我使用反射来设置字段值,但当我尝试将Short指定给Short时,会出现错误,因为isAssignable()返回false

private void setFieldValue(Object result, Field curField, Object value) throws NoSuchFieldException, IllegalAccessException {
    if (!curField.getType().isAssignableFrom(value.getClass())) {
        LOG.error("Can't set field value type mismatch: field class: " + curField.getType().getSimpleName() + ", value class: " + value.getClass().getSimpleName());
    } else {
        curField.set(result, value);
    }
}

任何关于如何进行反射以执行自动装箱的线索?

对于
int
字段
getType
将返回
int.class
。在自动驾驶之前,情况就是如此- 装箱是在Java中引入的,因此,正确地说,如果要保持向后兼容性,
Class.isAssignableFrom(Class)
在对象类型传递原语类型时返回
false

或者像你的情况一样:

int.class.isAssignableFrom(int.class)
将返回
true
,同时:

int.class.isAssignableFrom(Integer.class)
将返回
false


快速修复方法是编写一个方法,当对象类型出现时,检查该类型和原语,或者使用Jakarta Commons()之类的库中的类。

您需要手动检查该值是否可能是原语类型的包装,并对所有原语类型进行特殊处理。听起来很痛苦,按照@Danny的建议使用lib。

只需检查一个(并且只有一个)类是否是基元(class#isPrimitive())。如果是,请使用开关检查自动装箱。由于不涉及子类化,您可以编写一个帮助器方法,其中原语类是第一个,另一个是第二个。这样,补偿只需要8次比较,因此您不需要额外的依赖项。

在这里可能会有所帮助。该字段将接受已装箱的值(因为这是使用该值的唯一方法)。我不知道为什么
isAssignableFrom
是这样编程的。@Danny你的权利!很好用!是的,如果你更新ClassUtils.isAssignable(Class,Class,boolean),我会接受答案:D
ClassUtils.isAssignable(Class,Class)
ClassUtils.isAssignable(Class,Class,boolean)
相同,当你传递
true
时,只有当我使用布尔版本且布尔值设置为true时,类才起作用,也许其他版本有不同的默认值,这是2.6 apache commons。啊,是的,只要看一下源代码,我就搞不清加宽的意思了-它会说
长的
可以从
int
赋值,这与自动装箱不同-很好的地方