从 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 下的参数化属性类型?