当前位置: 首页 > 知识库问答 >
问题:

Java自省——奇怪的行为

庾鸿飞
2023-03-14

下面的代码是一个小示例,可以轻松重现问题。所以我有 String 类型的变量,它设置了默认值。我有3种方法:

  • getter
  • 塞特
  • 将字符串转换为布尔值的方便方法

自省不会将getter作为readMethod返回,将setter作为WriteMethod返回。相反,它将isTest()方法作为readMethod返回。setter为空。

从文档中我了解到,如果类型是boolean,那么" 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");
    }

}

有没有人对此有所了解?

补充信息:

  1. 顺序不会改变结果。isTest()方法始终被视为readmethod
  2. 如果我简单地将isTest()重命名为bsTest(),它会选择getter和setter作为readmethod和woremethod。所以它与“is-xxx”有关。

共有2个答案

彭成天
2023-03-14

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

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

冯胤
2023-03-14

根据 JavaBeans 规范,您获得的结果实际上是预期的结果。

引用第8.3.1段的简单属性:

如果我们发现一对匹配的< code>get

然后,引用第 8.3.2 段作为布尔属性:

这个<代码>是

在任一情况下,如果< code >为

从您的示例中,内测器正在检测isTestgetTest方法。由于isTest优先于getTest,因此它使用isTesttest属性的类型确定为boolean。但是,内测器希望设置器具有签名val setTest(boolean test)并且它没有找到它,因此设置器方法是null

需要注意的是,自省器不读取字段。它使用getter / setter方法的签名来确定存在哪些字段以及它们对应的类型。< code>isTest方法签名为< code>boolean类型的名为< code>test的属性指定,因此,不管< code>test的实际类型如何,内省器都会认为您的类具有属性< code>boolean test。

事实上,对于内观者来说,属性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());
    }

}
 类似资料:
  • 所以我更新了代码,添加了行所做的是将主线程置于Hibernate状态一段时间,因此jvm可以获得一些时间来创建一个新线程。我正在得到我的预期输出

  • 我发现了Java并发的奇怪行为。请参阅下面的下一段代码: 在我看来,这段代码应该挂起并永远等待,但是在控制台中的next out没有任何问题地完成了代码: 我试图找到一些关于如果线程死了通知锁的信息,但缺乏。我也没有在Java规范中找到任何信息。 但是如果我试图锁定其他对象(而不是thread对象),就会像我预期的那样工作得很好。

  • 如果有人理解java编译器为什么这么做,请解释一下。

  • 我在做Maven项目。我用log4j做了一个日志。但它在给定的文件中显示了一些starnge日志。我试图理解,为什么会出现这种奇怪的日志,但我不明白。请帮助我,为什么这些不需要的行会进入日志文件。 请帮我把这个拿开。 log.properties 我通过阅读这个链接创建了这个文件。 代码是 日志txt-(log.txt的一些起始行)

  • 我有以下代码来解析一个JSON文件: 要处理以下JSON文件: 如果我执行此代码,我将收到以下错误: 所以我开始一步一步地调试应用程序,看看part processing()中的哪个代码部分抛出了这个异常。令人惊讶的是,那里的所有代码都正常执行:没有抛出异常,也没有返回结果I except。 更让我惊讶的是,当我稍微改变第一种方法的代码时,它可以在不产生异常的情况下工作。 我不知道println方

  • 问题内容: 我遇到了来自java.util.Calendar的奇怪行为: 我想知道为什么会这样吗? 问题答案: 问题是您要从2013年1月30日开始使用日历。 然后,您将年份设置为2013年-这不是问题。 然后,您将月份设置为1(即2月)。您希望在这里发生什么?实际发生的情况是,它会记住需要将月份设置为1,而 不是 重新计算实际时间值。根据文档(Emphsis我的), 将 在您调用to时重新计算时