2013-03-12 79 views
2

从Java 1.7中,从BeanInfos获取超类的PropertyDescriptor失去属性映射如果该属性的返回类型需要通用参数。下面的测试代码阐释了这一点:Java 1.7的错误?:继承PropertyDescriptors的属性与泛型返回类型丢失属性映射

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")); 
    } 
} 

我意识到这读起来更像是一个bug报告,所以这里是我的问题:

  • 这是一个真正的错误,我的意思是,我忽视规范中的某些内容还是我没有遵循一些可以完全避免这种情况的最佳做法?

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

+0

当我在1.7.0_17下运行SCCE时,它会通过... – Durandal 2013-03-12 17:45:31

+0

它在1.6.0_24和1.7.0_09下失败。 – matts 2013-03-12 17:50:17

+0

对不起,忘了提及我的Java版本:1.7.0_07和1.6.0_43 – MisterEd 2013-03-12 18:28:45

回答

1

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