无法通过反射设置布尔值

时间:2017-03-04 00:52:52

标签: java reflection

我无法使用Java反射为字段设置Boolean值。 字段数据类型为java.lang.Boolean。但是,如果数据类型是基本类型,我可以设置值,即boolean

这是一个简单的VO,Boolean类型和原始类型:

public class TestVO {
    private Boolean bigBoolean;
    private boolean smallBoolean;
}

这是我的java反射代码:

public class TestClass {
    public static void main(String args[])
            throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
        TestVO testVO1 = new TestVO();

        Class testVO = testVO1.getClass();
        Field smallBooleanField = TestVO.class.getDeclaredField("smallBoolean");
        Field bigBooleanField = TestVO.class.getDeclaredField("bigBoolean");

        String name1 = smallBooleanField.getName();
        System.out.println("SmallBoolean Fieldname is: " + name1);

        smallBooleanField.setAccessible(true);

        // get the value of this private field
        Boolean fieldValue = (Boolean) smallBooleanField.get(testVO1);
        System.out.println("fieldValue = " + fieldValue);

        smallBooleanField.setAccessible(true);
        smallBooleanField.setBoolean(testVO1, true);

        // get the value of this private field
        fieldValue = (Boolean) smallBooleanField.get(testVO1);
        System.out.println("fieldValue = " + fieldValue);

        name1 = bigBooleanField.getName();
        System.out.println("bigBooleanField Fieldname is: " + name1);

        bigBooleanField.setAccessible(true);

        // get the value of this private field
        fieldValue = (Boolean) bigBooleanField.get(testVO1);
        System.out.println("fieldValue = " + fieldValue);

        bigBooleanField.setAccessible(true);
        bigBooleanField.setBoolean(testVO1, new Boolean(true));

        // get the value of this private field
        fieldValue = (Boolean) bigBooleanField.get(testVO1);
        System.out.println("fieldValue = " + fieldValue);

    }
}

输出是:

SmallBoolean Fieldname is: smallBoolean
fieldValue = false
fieldValue = true
bigBooleanField Fieldname is: bigBoolean
fieldValue = null
Exception in thread "main" java.lang.IllegalArgumentException: Can not set java.lang.Boolean field TestVO.bigBoolean to (boolean)true
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:175)
    at sun.reflect.UnsafeObjectFieldAccessorImpl.setBoolean(UnsafeObjectFieldAccessorImpl.java:90)
    at java.lang.reflect.Field.setBoolean(Field.java:795)
    at TestClass.main(TestClass.java:44)

我尝试使用bigBooleannew Boolean(true)Boolean.TRUE等设置true值。无效。

3 个答案:

答案 0 :(得分:4)

根据this,调用bigBoolean.setBoolean()来设置一个具有基本类型值的引用类型为Boolean的字段。在非反射等价物Boolean val = true中,编译器会将原始类型“true”转换(或框)为引用类型new Boolean(True),以便其类型检查将接受该语句。

使用反射时,类型检查仅在运行时进行,因此无法对值进行装箱。由于Inconvertible Types

,这会强制抛出IllegalArgumentException

答案 1 :(得分:1)

更改此行,它应该对您有用:

bigBooleanField.set(testVO1, Boolean.TRUE);

答案 2 :(得分:0)

我面临同样的问题而且理由不是反射原因是getter方法类型。如果您注意到boolean / Boolean,则IDE会创建一个getter方法,如isVariableName()而不是getVariableName()。如果您更改方法名称以获取类型,它将正常工作。