Jdk版本:1.8.0_131 作者出于学习阶段,如有问题请指正
来自API的解释:IndexedPropertyDescriptor描述了一个像数组一样的属性,并且具有索引的读取和/或索引的写入方法来访问数组的特定元素。 索引属性还可以提供简单的非索引读写方法。 如果这些存在,它们读取和写入由索引读取方法返回的类型的数组。
当前类和PropertyDescriptor的作用很相似,但是PropertyDescriptor提供的只是一个包装readMethod和writeMethod的类,如果当前属性具有两个方法,一个是getName(int n),返回的是数组的第N个名称,还有一个方法是[] getNames,那么这就需要IndexedPropertyDescriptor来进行包装,也可以用于反射来对属性进行包装。
构造器:
IndexedPropertyDescriptor(String propertyName, Class<?> beanClass) 当前构造器构造的write、read方法的名称和PropertyDescriptor一样,都是在属性名前加get/set前缀,并且认为默认的索引write、read方法和普通的非索引方法一致,建议如果能直接构造出四个方法的情况下不要调用此构造器 IndexedPropertyDescriptor(String propertyName, Class<?> beanClass,String readMethodName, String writeMethodName,String indexedReadMethodName, String indexedWriteMethodName) 当前构造器也是用得比较多的一种,直接传入read\write\indexedRead\indexedWrite方法的名字进行构造,构造过程中会将四个方法的名字构造成实际方法: public synchronized Method getIndexedReadMethod() { Method indexedReadMethod = this.indexedReadMethodRef.get(); if (indexedReadMethod == null) { Class<?> cls = getClass0(); if (cls == null || (indexedReadMethodName == null && !this.indexedReadMethodRef.isSet())) { // the Indexed readMethod was explicitly set to null. return null; } String nextMethodName = Introspector.GET_PREFIX + getBaseName(); if (indexedReadMethodName == null) { Class<?> type = getIndexedPropertyType0(); if (type == boolean.class || type == null) { indexedReadMethodName = Introspector.IS_PREFIX + getBaseName(); } else { indexedReadMethodName = nextMethodName; } } Class<?>[] args = { int.class }; indexedReadMethod = Introspector.findMethod(cls, indexedReadMethodName, 1, args); if ((indexedReadMethod == null) && !indexedReadMethodName.equals(nextMethodName)) { // no "is" method, so look for a "get" method. indexedReadMethodName = nextMethodName; indexedReadMethod = Introspector.findMethod(cls, indexedReadMethodName, 1, args); } setIndexedReadMethod0(indexedReadMethod); } return indexedReadMethod; } IndexedPropertyDescriptor(String propertyName, Method readMethod, Method writeMethod,Method indexedReadMethod, Method indexedWriteMethod) 当前构造器和上个构造器的作用类似,但是和上个构造器相比,少了从方法名构造方法的过程,这个构造器传入的要求是四个方法,而上个构造器会帮忙构造这四种方法 IndexedPropertyDescriptor(Class<?> bean, String base, Method read, Method write, Method readIndexed, Method writeIndexed) throws IntrospectionException { 当前构造器的方法和PropertyDescriptor的一样,将base作为属性名,具体base的处理见上一章对于PropertyDescriptor的解析中base的处理过程整个类重写了hashCode(1.5开始)和equals(1.4开始)方法,同时提供了合并两个PropertyDescriptor的方法:
IndexedPropertyDescriptor(PropertyDescriptor x, PropertyDescriptor y) { super(x,y); if (x instanceof IndexedPropertyDescriptor) { IndexedPropertyDescriptor ix = (IndexedPropertyDescriptor)x; try { Method xr = ix.getIndexedReadMethod(); if (xr != null) { setIndexedReadMethod(xr); } Method xw = ix.getIndexedWriteMethod(); if (xw != null) { setIndexedWriteMethod(xw); } } catch (IntrospectionException ex) { // Should not happen throw new AssertionError(ex); } } if (y instanceof IndexedPropertyDescriptor) { IndexedPropertyDescriptor iy = (IndexedPropertyDescriptor)y; try { Method yr = iy.getIndexedReadMethod(); if (yr != null && yr.getDeclaringClass() == getClass0()) { setIndexedReadMethod(yr); } Method yw = iy.getIndexedWriteMethod(); if (yw != null && yw.getDeclaringClass() == getClass0()) { setIndexedWriteMethod(yw); } } catch (IntrospectionException ex) { // Should not happen throw new AssertionError(ex); } } }其他的方法没有太多值得赘述的地方,至于用法,可以见上章的PropertyDescriptor的用法,通过反射先构造,后调用其get\set方法,只是IndexedPropertyDescriptor多了一个索引get和索引set的方法
