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

匆匆过客 提交于 2019-11-28 21:36:45

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

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[]{});
}
Anton Rybochkin

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!