2

从 Java 1.7 开始,如果属性的返回类型采用泛型参数,则从 BeanInfos 获取超类的 PropertyDescriptor 将丢失其属性映射。下面的测试代码说明了这种行为:

import java.beans.*;
import java.util.*;
import org.junit.Test;
import static org.junit.Assert.*;

public class BeanInfoTest {

    public interface Super {

        public List<String> getSuperList();

        public void setSuperList(List<String> list);

        public String[] getSuperArray();

        public void setSuperArray(String[] array);
    }

    public interface Sub extends Super {

        public List<String> getSubList();

        public void setSubList(List<String> list);
    }

    public static class SuperBeanInfo extends SimpleBeanInfo {

        private PropertyDescriptor[] props = new PropertyDescriptor[2];

        public SuperBeanInfo() throws IntrospectionException {
            props[0] = new PropertyDescriptor("superList", Super.class);
            props[1] = new PropertyDescriptor("superArray", Super.class);

            props[0].setValue("superListAttribute", new Object());
            props[1].setValue("superArrayAttribute", new Object());
        }

        @Override
        public PropertyDescriptor[] getPropertyDescriptors() {
            return props;
        }
    }

    public static class SubBeanInfo extends SimpleBeanInfo {

        private PropertyDescriptor[] props = new PropertyDescriptor[1];

        public SubBeanInfo() throws IntrospectionException {
            props[0] = new PropertyDescriptor("subList", Sub.class);
            props[0].setValue("subListAttribute", new Object());
        }

        @Override
        public PropertyDescriptor[] getPropertyDescriptors() {
            return props;
        }

        @Override
        public BeanInfo[] getAdditionalBeanInfo() {
            try {
                return new BeanInfo[]{Introspector.getBeanInfo(Super.class)};
            } catch (IntrospectionException ex) {
                throw new RuntimeException(ex);
            }
        }
    }

    @Test
    public void testBeanInfo() throws IntrospectionException {

        System.out.println(System.getProperty("java.version"));

        PropertyDescriptor[] pds = Introspector.getBeanInfo(
                Sub.class).getPropertyDescriptors();

        List<String> allAttrNames = new ArrayList<String>();
        for (PropertyDescriptor pd : pds)
            allAttrNames.addAll(Collections.list(pd.attributeNames()));


        // always passes
        assertArrayEquals(pds, new PropertyDescriptor[]{
                    new PropertyDescriptor("subList", Sub.class),
                    new PropertyDescriptor("superArray", Super.class),
                    new PropertyDescriptor("superList", Super.class)
                });
        assertTrue(allAttrNames.contains("superArrayAttribute"));
        assertTrue(allAttrNames.contains("subListAttribute"));


        // passes under 1.6_43; fails under 1.7_07
        assertTrue(allAttrNames.contains("superListAttribute"));
    }
}

我意识到这更像是一份错误报告,所以这是我的问题:

  • 这真的是一个错误,我的意思是,我是否忽略了规范中的某些内容,或者我没有遵循一些可以完全避免这种情况的最佳实践?

  • 如果没有,是否有其他人遇到过这个问题和/或知道任何解决方法可以让人们继续使用 Java 1.7 下的参数化属性类型?

4

1 回答 1

1

显然这是我正在运行的版本(1.7.0_07)中的一个错误。更新到 1.7.0_17 后,问题就解决了。

于 2013-03-14T20:46:03.757 回答