Java内省 – 奇怪的行为

前端之家收集整理的这篇文章主要介绍了Java内省 – 奇怪的行为前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
下面的代码是一个很容易重现问题的小例子.所以我有一个类型为String的变量,在其上设置一个默认值.我有3种方法

吸气剂
>设定者
>方便的方法,将字符串转换为布尔值

内部回调并不返回getMethod和setter作为writeMethod的getter.而是将isTest()方法作为readMethod返回.设定器是空的.

从文档中我了解到,如果类型是一个布尔值,那么“is”方法的优先级高于get,但是类型是String,所以甚至找不到“is-xxx”方法是没有意义的.

public class Test {
    public class Arguments {
        private String test = Boolean.toString(true);

        public boolean isTest() {
            return Boolean.parseBoolean(test);
        }

        public String getTest() {
            return test;
        }

        public void setTest(String test) {
            this.test = test;
        }
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws IntrospectionException {
        BeanInfo info = Introspector.getBeanInfo(Arguments.class);
        System.out.println("Getter: " + info.getPropertyDescriptors()[1].getReadMethod());
        System.out.println("Setter: " + info.getPropertyDescriptors()[1].getWriteMethod());
        PropertyDescriptor descr = new PropertyDescriptor("test",Arguments.class);
        System.out.println("T");
    }

}

有没有人有这方面的见解?

附加信息:

>订单不会改变结果. isTest()方法总是被看作readMethod
>如果我简单地将isTest()重命名为bsTest(),它将getter和setter选择为readMethod和writeMethod.所以它与“is-xxx”有关.

解决方法

你得到的结果实际上是预期的结果,根据 JavaBeans specification.

引用段落8.3.1简单属性

If we discover a matching pair of get<PropertyName> and set<PropertyName> methods
that take and return the same type,then we regard these methods as defining a read-write property whose name will be <propertyName>.

然后,对布尔属性引用段落8.3.2:

This is<PropertyName> method may be provided instead of a get<PropertyName> method,or it may be provided in addition to a get<PropertyName> method.

In either case,if the is<PropertyName> method is present for a boolean property then we will use the is<PropertyName> method to read the property value.

从您的示例中,Introspector将检测到isTest和getTest方法.由于isTest优先于getTest,因此它使用isTest将测试属性的类型确定为布尔值.但是,Introspector希望setter具有签名void setTest(boolean test),并且没有找到它,因此setter方法为null.

需要注意的是Introspector不读字段.它使用getter / setter方法的签名来确定哪些字段存在及其相应的类型. isTest方法签名指定一个名为test的类型为boolean的属性,因此,无论实际的测试类型如何,Introspector将认为您的类具有属性布尔测试.

事实上,对于所有的内省人来说,物业测试可能甚至不存在!您可以使用以下代码说服自己:

class Test {

    public class Arguments {
        public boolean isTest() {
            return true;
        }
    }

    public static void main(String[] args) throws IntrospectionException {
        BeanInfo info = Introspector.getBeanInfo(Arguments.class);
        System.out.println("Getter: " + info.getPropertyDescriptors()[1].getReadMethod());
        System.out.println("Name of property: " + info.getPropertyDescriptors()[1].getName());
    }

}

猜你在找的Java相关文章