加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

Java内省 – 奇怪的行为

发布时间:2020-12-14 05:10:06 所属栏目:Java 来源:网络整理
导读:下面的代码是一个很容易重现问题的小例子.所以我有一个类型为String的变量,在其上设置一个默认值.我有3种方法: 吸气剂 设定者 方便的方法,将字符串转换为布尔值 内部回调并不返回getMethod和setter作为writeMethod的getter.而是将isTest()方法作为readMetho
下面的代码是一个很容易重现问题的小例子.所以我有一个类型为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());
    }

}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读