Java 8 interface default method doesn't seem to declare property

后端 未结 3 1579
感情败类
感情败类 2020-12-14 10:17

In my application I run into a problem that when a getter in a class is defaulted in an interface only (Java 8 feature), there is no Java Beans property as a result. I.e. f

相关标签:
3条回答
  • 2020-12-14 10:39

    I don't know if my answer will be helpful, but I solved similar problem by using BeanUtils.getPropertyDescriptors(clazz) from Spring. It understands default methods.

    0 讨论(0)
  • 2020-12-14 10:49

    A quick work-around:

    try {
        return PropertyUtils.getProperty(bean, property);
    }
    catch (NoSuchMethodException e) {
        String getMethod = "get" + property.substring(0, 1).toUpperCase() + property.substring(1);
        return MethodUtils.invokeMethod(bean, getMethod, new Object[]{});
    }
    
    0 讨论(0)
  • 2020-12-14 11:00

    This seems to be indeed an erroneous omission in the Beans Introspector. Here is a workaround other than not using default methods:

    public static void main (String[] arguments) throws Exception {
        testBean(new Bean1());
        System.out.println();
        testBean(new Bean2());
    }
    static void testBean(Object bean) throws Exception {
        PropertyDescriptor[] pd
            = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
        System.out.println(Arrays.stream(pd)
            .map(PropertyDescriptor::getName).collect(Collectors.joining(", ")));
        for(PropertyDescriptor p: pd)
            System.out.println(p.getDisplayName()+": "+p.getReadMethod().invoke(bean));
    }
    public interface Foo {
        default String getFoo() {
            return "default foo";
        }
    }
    public static class Bean1 implements Foo {
        @Override
        public String getFoo() {
            return "special foo";
        }
    }
    public static class Bean2BeanInfo extends SimpleBeanInfo {
        private final BeanInfo ifBeanInfo;
        public Bean2BeanInfo() throws IntrospectionException {
            ifBeanInfo=Introspector.getBeanInfo(Foo.class);
        }
        @Override
        public BeanInfo[] getAdditionalBeanInfo() {
            return new BeanInfo[]{ifBeanInfo};
        }
    }
    public static class Bean2 implements Foo { }
    
    class, foo
    class: class helper.PropTest$Bean1
    foo: special foo
    class, foo
    class: class helper.PropTest$Bean2
    foo: default foo
    
    0 讨论(0)
提交回复
热议问题