Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java内省-奇怪的行为_Java_Javabeans_Introspection - Fatal编程技术网

Java内省-奇怪的行为

Java内省-奇怪的行为,java,javabeans,introspection,Java,Javabeans,Introspection,下面的代码是一个很容易重现问题的小示例。所以我有一个字符串类型的变量,在它上面设置了一个默认值。我有三种方法: 吸气剂 塞特 将字符串转换为布尔值的便利方法 内省不会将getter作为readMethod返回,将setter作为writeMethod返回。相反,它返回isTest()方法作为readMethod。setter是空的 从文档中我了解到,如果类型是布尔值,“is”方法的优先级高于get,但是类型是String,所以即使查找“is xxx”方法也没有意义 有没有人对此有所了解 其他

下面的代码是一个很容易重现问题的小示例。所以我有一个字符串类型的变量,在它上面设置了一个默认值。我有三种方法:

  • 吸气剂
  • 塞特
  • 将字符串转换为布尔值的便利方法
内省不会将getter作为readMethod返回,将setter作为writeMethod返回。相反,它返回isTest()方法作为readMethod。setter是空的

从文档中我了解到,如果类型是布尔值,“is”方法的优先级高于get,但是类型是String,所以即使查找“is xxx”方法也没有意义

有没有人对此有所了解

其他信息:

  • 命令不会改变结果。isTest()方法始终被视为readMethod
  • 如果我只是将isTest()重命名为bsTest(),它会选择getter和setter作为readMethod和writeMethod。所以它与“is xxx”有关

  • 实际成员与
    内省者
    完全无关。例如,您可以有一个
    getName()
    方法,该方法只返回一个固定的
    字符串
    ,内省者会发现它是名为“name”的成员的getter。如果成员不存在,您甚至可以拥有setter。您甚至可以为
    内省器提供一个接口,它将根据该接口确定属性,即使没有任何真正的成员


    换句话说,属性是由getter和setter方法的存在而不是通过实际搜索变量来确定的。

    根据

    引用第8.3.1段中的简单特性:

    如果我们发现一对匹配的
    get
    set
    方法 接受并返回相同类型,那么我们将这些方法视为定义一个名为
    的读写属性

    然后,引用第8.3.2段中的布尔属性:

    可以提供此
    is
    方法来代替
    get
    方法,也可以在
    get
    方法之外提供此方法

    在任何一种情况下,如果布尔属性存在
    is
    方法,那么我们将使用
    is
    方法读取属性值

    从您的示例中,内省器同时检测
    isTest
    getTest
    方法。由于
    isTest
    的优先级高于
    getTest
    ,因此它使用
    isTest
    test
    属性的类型确定为
    boolean
    。但是,内省者希望setter拥有签名
    void setTest(boolean test)
    ,但它没有找到它,因此setter方法是
    null

    需要注意的是,内省者不会读取字段。它使用getter/setter方法的签名来确定存在哪些字段及其对应的类型<代码> istest方法签名指定类型为<代码> test <代码>的类型<代码>布尔,因此,无论实际代码类型<代码>测试>代码>,内省者都会考虑您的类具有一个属性“代码>布尔测试 < < /P>”。 事实上,对于所有内省者来说,属性
    test
    可能根本不存在!您可以通过以下代码说服自己:

    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());
        }
    
    }
    

    如果在类的末尾声明
    isTest
    方法,会发生什么?这可能是因为这是第一次出现,所以它被识别为布尔值,因此setter与类型String不匹配。不,这没有意义,但显然这是他们决定的(或者这是一个bug)。除了停止用字符串表示布尔值外,您对此无能为力:DI在初始文本中添加了更多信息。顺序对结果没有影响。我同意Tunaki的观点,如果你正在做一些元编程,你可以用一些参数强制它按照你的意愿工作:
    PropertyDescriptor descr=newpropertydescriptor(“test”,Arguments.class,“getTest”,“setTest”)
    您提到“它使用isTest将测试属性的类型确定为boolean”,但测试类型明确定义为String。还是因为方法的返回值是布尔值而将类型定义为布尔值?@Quirexx内省者不读取字段。它使用getter/setter方法的签名来确定存在哪些字段及其对应的类型
    isTest
    signature为名为boolean类型的“test”的属性指定,而不考虑“test”的实际类型,因此它只查看方法并遵循JavaBeans命名约定来确定属性。如果你这样看,结果确实是正确的。现在它有意义了。谢谢
    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());
        }
    
    }